欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript類的繼承操作實例總結(jié)

 更新時間:2018年12月20日 08:37:44   作者:huansky  
這篇文章主要介紹了JavaScript類的繼承操作,結(jié)合實例形式總結(jié)分析了JavaScript面向?qū)ο蟪绦蛟O(shè)計中類的繼承常見實現(xiàn)方式與操作技巧,需要的朋友可以參考下

本文實例總結(jié)了JavaScript類的繼承操作。分享給大家供大家參考,具體如下:

一、類式繼承

首先要做的是創(chuàng)建構(gòu)造函數(shù)。按慣例,其名稱就是類名,首字母應(yīng)該大寫。在構(gòu)造函數(shù)中,創(chuàng)建實例屬性要用關(guān)鍵字this 。類的方法則被添加到prototype對象中。要創(chuàng)建該類的實例,只需結(jié)合關(guān)鍵字new調(diào)用這構(gòu)造函數(shù)即可。

/* Class Person. */
function Person(name) {
 this.name = name;
}
Person.prototype.getName = function() {
 return this.name;
}
var reader = new Person('John Smith');
reader.getName();

二、原型鏈

JavaScript的每個對象都有一個名為prototype的屬性,這個屬性要么指向另一個對象,要么是null.在訪問對象的某個成員時,如果這個成員未見于當(dāng)前對象,那么就會到prototype所指的對象中去查找。如果還是沒有找到,那么就會沿著原型鏈逐一訪問每個原型對象,直到找到這個成員。這意味著讓一個類繼承另一個類,只需將子類的prototype設(shè)置為超類的一個實例即可。

為了讓Author繼承Person,必須手工將Author的prototype設(shè)置為Person的一個實例。最后一步是將prototypeconstruct屬性重設(shè)為Author(因為prototype屬性設(shè)置為Person的實例)時,其construct屬性被抹除了。

function Author(name, books) {
 Person.call(this, name); // Call the superclass' constructor in the scope of this.
 this.books = books; // Add an attribute to Author.
}
Author.prototype = new Person(); // Set up the prototype chain.
Author.prototype.constructor = Author; // Set the constructor attribute to Author.
Author.prototype.getBooks = function() { // Add a method to Author.
 return this.books;
};
var author = [];
author[0] = new Author('Dustin Diaz', ['JavaScript Design Patterns']);
author[1] = new Author('Ross Harmes', ['JavaScript Design Patterns']);
console.log(author[1].getName());
console.log(author[1].getBooks());

三、extend函數(shù)

為了簡化類的聲明,可以把派生子類的整個過程包裝在一個名為extend的函數(shù)中。它的作用與其他語言的extend關(guān)鍵字類似,即基于一個給定的類的結(jié)構(gòu)創(chuàng)建一個新的類:

function extend(subClass, superClass) {
 var F = function() {};
 F.prototype = superClass.prototype;
 subClass.prototype = new F();
 subClass.prototype.constructor = subClass;
}

其實所做的事與之前的是一樣的。它先設(shè)置了prototype,然后再將其constructor重設(shè)為恰當(dāng)?shù)闹?。并且中間利用了一個空函數(shù),這樣就可以避免創(chuàng)建超類的實例。使用extend繼承的寫法:

function Person(name) {
 this.name = name;
}
Person.prototype.getName = function() {
 return this.name;
}
/* Class Author. */
function Author(name, books) {
 Person.call(this, name);
 this.books = books;
}
extend(Author, Person);
Author.prototype.getBooks = function() {
 return this.books;
};

但上面的存在一個問題就是超類Person的名稱被固化在Author類的聲明當(dāng)中。更普世性的做法應(yīng)該像下面這樣:

/* Extend function, improved. */
function extend(subClass, superClass) {
 var F = function() {};
 F.prototype = superClass.prototype;
 subClass.prototype = new F();
 subClass.prototype.constructor = subClass;
 subClass.superclass = superClass.prototype;
 if(superClass.prototype.constructor == Object.prototype.constructor) {
  superClass.prototype.constructor = superClass;
 }
}
/* Class Author. */
function Author(name, books) {
 Author.superclass.constructor.call(this, name);
 this.books = books;
}
extend(Author, Person);
Author.prototype.getBooks = function() {
 return this.books;
};
Author.prototype.getName = function() {
 var name = Author.superclass.getName.call(this);
 return name + ', Author of ' + this.getBooks().join(', ');
};

這個extend改進(jìn)之后,多了一個superclass的屬性,這個屬性可以弱化Author和Person之間的耦合。extend后面三行用來確保超類的construtor已經(jīng)被正確設(shè)置了。有了superclass的屬性,就可以直接調(diào)用超類中的方法。這在既要重新定義超類的某個方法而又想訪問其在超類中的實現(xiàn)時可以派上用場。例如,為了用一個新的getName的方法重新定義Person類中的同名方法,你可以先用Author.superclass.getName獲得作者的名字,然后再次基礎(chǔ)上添加新的信息。

四、原型繼承

原型式繼承與類式繼承截然不同,我們在學(xué)習(xí)他的時候,最好忘記自己關(guān)于類和實例的一切知識,只從對象的角度來思考。使用原型式繼承時,并不需要用類來定義對象的結(jié)構(gòu),只需直接創(chuàng)建一個對像就可以。這個對象隨后可以被新的對象使用,該對象被稱為原型對象。

下面使用原型對象來重新設(shè)計上面Person和Author:

var Person = {
 name: 'default name',
 getName: function() {
  return this.name;
 }
};
var reader = clone(Person);
alert(reader.getName()); // This will output 'default name'.
reader.name = 'John Smith';
alert(reader.getName()); // This will now output 'John Smith'.

clone函數(shù)可以用來創(chuàng)建新的類Person對象,創(chuàng)建一個空對象,并且該對象的原型對象被設(shè)置為person。當(dāng)新對象中找不到某個方法時就會在原型對象中查找。

你不必去為了創(chuàng)建Author而定義一個Person子類,只要執(zhí)行一次克隆就可以:

var Author = clone(Person);
Author.books = []; // Default value.
Author.getBooks = function() {
 return this.books;
}

然后你可以重定義該克隆中的方法和屬性??梢孕薷腜erson的默認(rèn)值。也可以添加新的屬性和方法。這樣一來就創(chuàng)建了一個新的原型對象,你可以將其用于創(chuàng)建新的Author對象:

var author = [];
author[0] = clone(Author);
author[0].name = 'Dustin Diaz';
author[0].books = ['JavaScript Design Patterns'];
author[1] = clone(Author);
author[1].name = 'Ross Harmes';
author[1].books = ['JavaScript Design Patterns'];
author[1].getName();
author[1].getBooks();

clone函數(shù)的寫法:

function clone(object) {
  function F() {}
  F.prototype = object;
  return new F;
}

五、原型繼承和類式繼承之間的比較

可以自己去總結(jié)、
從內(nèi)存,適用范圍,優(yōu)缺點等方面去分析

六、摻元類

有一種重用代碼的方法不需要用到嚴(yán)格的繼承,如果想把一個函數(shù)運用到多個類當(dāng)中,可以通過擴(kuò)充的方法讓這些類共享函數(shù)。其實際大體做法就是:先創(chuàng)建一個包含各種通用的方法類,然后再擴(kuò)充其他類,這種包含通用方法類稱為摻元類,他們通常不會被實例化和直接調(diào)用,其存在的目的是向其他類提供自己的方法。

var Mixin = function() {};
Mixin.prototype = {
 serialize: function() {
  var output = [];
  for(key in this) {
   output.push(key + ': ' + this[key]);
  }
  return output.join(', ');
 }
};
augment(Author, Mixin);
var author = new Author('Ross Harmes', ['JavaScript Design Patterns']);
var serializedString = author.serialize();
function augment(receivingClass, givingClass) {
 for(methodName in givingClass.prototype) {
  if(!receivingClass.prototype[methodName]) {
   receivingClass.prototype[methodName] = givingClass.prototype[methodName];
  }
 }
}

但是有時候你并不需要所有的方法,因此我們還需要提供額外的參數(shù)來選擇我們所需要的方法。如果不提供,那就全部復(fù)制。

function augment(receivingClass, givingClass) {
 if(arguments[2]) { // Only give certain methods.
  for(var i = 2, len = arguments.length; i < len; i++) {
   receivingClass.prototype[arguments[i]] = givingClass.prototype[arguments[i]];
  }
 }
 else { // Give all methods.
  for(methodName in givingClass.prototype) {
   if(!receivingClass.prototype[methodName]) {
    receivingClass.prototype[methodName] = givingClass.prototype[methodName];
   }
  }
 }
}

更多關(guān)于JavaScript相關(guān)內(nèi)容還可查看本站專題:《javascript面向?qū)ο笕腴T教程》、《JavaScript錯誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript數(shù)學(xué)運算用法總結(jié)

希望本文所述對大家JavaScript程序設(shè)計有所幫助。

相關(guān)文章

  • js計算精度問題小結(jié)

    js計算精度問題小結(jié)

    js計算精度問題小結(jié),需要的朋友可以參考一下
    2013-04-04
  • three.js中3D視野的縮放實現(xiàn)代碼

    three.js中3D視野的縮放實現(xiàn)代碼

    這篇文章主要為大家詳細(xì)介紹了three.js中3D視野的縮放實現(xiàn)代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • Javascript中的函數(shù)聲明與函數(shù)表達(dá)式(奇技淫巧)

    Javascript中的函數(shù)聲明與函數(shù)表達(dá)式(奇技淫巧)

    Javascript有很多有趣的用法,在Google Code Search里能找到不少,今天從火丁筆記看到的,非常不錯,推薦大家看下。
    2011-03-03
  • 微信小程序里引入SVG矢量圖標(biāo)的方法

    微信小程序里引入SVG矢量圖標(biāo)的方法

    這篇文章主要介紹了微信小程序里引入SVG矢量圖標(biāo)的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • js實現(xiàn)精確到毫秒的倒計時效果

    js實現(xiàn)精確到毫秒的倒計時效果

    這篇文章主要為大家詳細(xì)介紹了js實現(xiàn)精確到毫秒的倒計時效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-08-08
  • 基于JavaScript實現(xiàn)百葉窗動畫效果不只單純flas可以實現(xiàn)

    基于JavaScript實現(xiàn)百葉窗動畫效果不只單純flas可以實現(xiàn)

    看到這種百葉窗效果的動畫,以為是用flash做的,下面通過本文給大家介紹基于JavaScript實現(xiàn)百葉窗動畫效果,需要的朋友參考下吧
    2016-02-02
  • JavaScript中this機制是如何真正工作的

    JavaScript中this機制是如何真正工作的

    JavaScript中this機制提供了更優(yōu)雅的方式來隱含地“傳遞”一個對象引用,導(dǎo)致更加干凈的API設(shè)計和更容易的復(fù)用,this既不是函數(shù)自身的引用,也不是函數(shù)詞法作用域的引用,this實際上是在函數(shù)被調(diào)用時建立的一個綁定,它指向什么是完全由函數(shù)被調(diào)用的調(diào)用點來決定的
    2023-11-11
  • 淺談JavaScript中的parseInt()的妙用

    淺談JavaScript中的parseInt()的妙用

    本文主要介紹了JavaScript中的parseInt()的妙用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07
  • js實現(xiàn)TAB切換對應(yīng)不同顏色的代碼

    js實現(xiàn)TAB切換對應(yīng)不同顏色的代碼

    這篇文章主要介紹了js實現(xiàn)TAB切換對應(yīng)不同顏色的代碼,涉及javascript頁面元素的遍歷及樣式的動態(tài)操作技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-08-08
  • js運動應(yīng)用實例解析

    js運動應(yīng)用實例解析

    這篇文章主要針對js運動應(yīng)用進(jìn)行實例解析
    2015-12-12

最新評論