国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

js繼承的理解

BlackFlagBin / 2011人閱讀

摘要:創(chuàng)建自定義的構(gòu)造函數(shù)之后,其原型對(duì)象只會(huì)取得屬性,其他方法都是從繼承來的。優(yōu)缺點(diǎn)寄生式繼承在主要考慮對(duì)象而不是創(chuàng)建自定義類型和構(gòu)造函數(shù)時(shí),是十分有用的。

原文鏈接:https://kongchenglc.coding.me...

1.原型鏈

??js的繼承機(jī)制不同于傳統(tǒng)的面向?qū)ο笳Z言,采用原型鏈實(shí)現(xiàn)繼承,基本思想是利用原型讓一個(gè)引用類型繼承另一個(gè)引用類型的屬性和方法。理解原型鏈必須先理解原型,以下是對(duì)于原型的一些解釋:

無論什么時(shí)候,只要?jiǎng)?chuàng)建了一個(gè)新函數(shù),就會(huì)根據(jù)一組特定規(guī)則為該函數(shù)創(chuàng)建一個(gè)prototype屬性。這個(gè)屬性指向函數(shù)的原型對(duì)象,所有原型對(duì)象都會(huì)自動(dòng)獲得一個(gè)constructor屬性,這個(gè)屬性是一個(gè)指向prototype屬性所在函數(shù)的指針。創(chuàng)建自定義的構(gòu)造函數(shù)之后,其原型對(duì)象只會(huì)取得constructor屬性,其他方法都是從Object繼承來的。當(dāng)調(diào)用構(gòu)造函數(shù)創(chuàng)建一個(gè)新實(shí)例之后,該實(shí)例的內(nèi)部包含一個(gè)指針,指向構(gòu)造函數(shù)的原型對(duì)象,即[[Prototype]],在瀏覽器中為_proto_

??也就是說,構(gòu)造函數(shù)和實(shí)例實(shí)際上都是存在一個(gè)指向原型的指針,構(gòu)造函數(shù)指向原型的指針為其prototype屬性。實(shí)例也包含一個(gè)不可訪問的指針[[Prototype]](實(shí)際在瀏覽器中可以用_proto_訪問),而原型鏈的形成真正依賴的是_proto_而非[[Prototype]]

舉個(gè)例子

下邊是一個(gè)最簡(jiǎn)單的繼承方式的例子:用父類實(shí)例充當(dāng)子類原型對(duì)象。

function SuperType(){                        
    this.property = true;
    this.arr = [1];
}
SuperType.prototype.getSuperValue = function(){
    return this.property;
};
function SubType(){
    this.subproperty = false;
}
SubType.prototype = new SuperType();              
//在此繼承,SubType的prototype為SuperType的一個(gè)實(shí)例
SubType.prototype.getSubValue = function(){
    return this.subproperty;
};
var instance = new SubType();
var instance2 = new SubType();                                   
c(instance.getSuperValue());                      //true
c(instance.getSubValue());                        //false
c(instance.__proto__.prototype);                  //undefined
//SubType繼承了SuperType,SuperType繼承了Object。
//instance的_proto_是SubType的原型對(duì)象,即SubType.prototype。
//而SubType.prototype又是SuperType的一個(gè)實(shí)例。
//則instance._proto_.prototype為undefined,
//因?yàn)镾uperType的實(shí)例對(duì)象不包含prototype屬性。
instance.arr.push(2);
c(instance.arr);                                  //[1,2]
c(instance2.arr);                                 //[1,2]
//子類們共享引用屬性

需要注意的一點(diǎn):無論以什么方式繼承,請(qǐng)謹(jǐn)慎使用將對(duì)象字面量賦值給原型的方法,這樣會(huì)重寫原型鏈。

優(yōu)缺點(diǎn)

??原型鏈繼承方式的優(yōu)點(diǎn)在于簡(jiǎn)單,而缺點(diǎn)也十分致命:

子類之間會(huì)共享引用類型屬性

創(chuàng)建子類時(shí),無法向父類構(gòu)造函數(shù)傳參

2.借用構(gòu)造函數(shù)

??又叫經(jīng)典繼承,借用構(gòu)造函數(shù)繼承的主要思想:在子類型構(gòu)造函數(shù)的內(nèi)部調(diào)用超類型構(gòu)造函數(shù),即用call()apply()方法給子類中的this執(zhí)行父類的構(gòu)造函數(shù),使其擁有父類擁有的屬性實(shí)現(xiàn)繼承,這種繼承方法完全沒有用到原型。下邊是借用構(gòu)造函數(shù)的實(shí)現(xiàn):

function SuperType(){                                 
    this.colors = ["red","blue","green"];
}
function SubType(){
    SuperType.call(this);     //借用構(gòu)造函數(shù)
}
var instance1 = new SubType();
instance1.colors.push("black");
c(instance1.colors);          //["red","blue","green","black"]
var instance2 = new SubType();
c(instance2.colors);          //["red","blue","green"]
舉個(gè)例子

??借用構(gòu)造函數(shù),相當(dāng)于將父類擁有的屬性在子類的構(gòu)造函數(shù)也寫了一遍,使子類擁有父類擁有的屬性,這種方法在創(chuàng)建子類實(shí)例時(shí),可以向父類構(gòu)造函數(shù)傳遞參數(shù) 。

function SuperType(name){           
    this.name = name;
}
function SubType(name){
    SuperType.call(this,name);          //借用構(gòu)造函數(shù)模式傳遞參數(shù)
    this.age = 29;
}
var instance = new SubType("something");
c(instance.name);                       //something
c(instance.age);                        //29
優(yōu)缺點(diǎn)

??借用構(gòu)造函數(shù)模式,不同于原型式繼承和原型模式,它不會(huì)共享引用類型屬性,而且也可以向超類型構(gòu)造函數(shù)傳遞參數(shù)。但是相對(duì)的,由于不會(huì)共享屬性,也無法實(shí)現(xiàn)代碼復(fù)用,相同的函數(shù)在每個(gè)實(shí)例中都有一份。為了實(shí)現(xiàn)代碼復(fù)用,提示效率,大神們又想出了下邊的繼承方法。

3.組合繼承

組合繼承有時(shí)也叫偽經(jīng)典繼承,是將原型鏈和借用構(gòu)造函數(shù)的技術(shù)組合到一塊,從而發(fā)揮二者之長(zhǎng)的一種繼承模式。

??即用原型鏈實(shí)現(xiàn)對(duì)原型屬性和方法的繼承(需要共享的),通過借用構(gòu)造函數(shù)實(shí)現(xiàn)對(duì)實(shí)例屬性的繼承(不共享的)。這樣的方法實(shí)現(xiàn)了函數(shù)復(fù)用,而且每個(gè)實(shí)例擁有自己的屬性。

舉個(gè)例子
function SuperType(name) {                       //父類的實(shí)例屬性
    this.name = name;
    this.colors = ["red", "blue", "green"];      
}
SuperType.prototype.sayName = function() {       //父類的原型屬性
    c(this.name);
};

function SubType(name, age) {                    //借用構(gòu)造函數(shù)繼承實(shí)例屬性
    SuperType.call(this, name);
    this.age = age;
}
SubType.prototype = new SuperType();             //原型鏈繼承原型屬性
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function() {
    c(this.age);
};
var instance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
c(instance1.colors);        //"red,blue,green,black"
delete instance1.colors;    
//刪除從實(shí)例屬性繼承來的colors,讀取colors會(huì)成為從原型繼承來的實(shí)例屬性
c(instance1.colors);        //"red,blue,green"
instance1.sayName();        //Nicholas
instance1.sayAge();         //29
var instance2 = new SubType("Greg", 27);
c(instance2.colors);        //"red,blue,green"
instance2.sayName();        //Greg
instance2.sayAge();         //27
優(yōu)缺點(diǎn)

這是所有繼承方式中最常用的,它的優(yōu)點(diǎn)也十分明顯:

可以在創(chuàng)建子類實(shí)例時(shí)向父類構(gòu)造函數(shù)傳參。

引用類型屬性的值可以不共享。

可以實(shí)現(xiàn)代碼復(fù)用,即可以共享相同的方法。

但是這種方法依然有一點(diǎn)不足,調(diào)用了兩次父類的構(gòu)造函數(shù),最后會(huì)講到一種理論上接近完美的繼承方式,即寄生組合式繼承。

4.原型式繼承

??原型式繼承借助原型基于已有對(duì)象創(chuàng)建新對(duì)象,需要一個(gè)對(duì)象作為另一個(gè)對(duì)象的基礎(chǔ):

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

??上邊段代碼就是原型式繼承的核心代碼,先創(chuàng)建一個(gè)臨時(shí)性的構(gòu)造函數(shù),然后將傳入的對(duì)象作為這個(gè)構(gòu)造函數(shù)的原型,最后返回這個(gè)臨時(shí)類型的一個(gè)新實(shí)例。

舉個(gè)例子
var person = {
    name: "Nicholas",
    friends: ["Shelby", "Court", "Van"]
};
var anotherPerson = object(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");
var yetAnotherPerson = object(person);      //在此繼承
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie");
c(person.friends);              //["Shelby","Court","Van","Rob","Barbie"]
c(person.name);                 //Nicholas
c(anotherPerson.name);          //Greg
c(yetAnotherPerson.name);       //Linda
delete yetAnotherPerson.name;   
//刪除子類的屬性,就會(huì)解除對(duì)父類屬性的屏蔽,暴露出父類的name屬性
c(yetAnotherPerson.name);       //Nicholas

??從上邊的代碼顯示,由object(注意首字母小寫,不是對(duì)象的構(gòu)造函數(shù))產(chǎn)生的兩個(gè)子類會(huì)共享父類的引用屬性,其中friends數(shù)組是共享的,anotherPerson和yetAnotherPerson都是繼承自person。實(shí)際上相當(dāng)于創(chuàng)建了兩個(gè)person對(duì)象的副本,但可以在產(chǎn)生之后擁有各自的實(shí)例屬性。

ECMAScript5新增了Object.create()方法規(guī)范化了原型式繼承,這個(gè)方法接受兩個(gè)參數(shù):

一個(gè)作為新對(duì)象原型的對(duì)象(可以是對(duì)象或者null)

另一個(gè)為新對(duì)象定義額外屬性的對(duì)象(可選,這個(gè)參數(shù)的格式和Object.defineProperties()方法的第二個(gè)參數(shù)格式相同,每個(gè)屬性都是通過自己的描述符定義的)

??下邊是一個(gè)例子:

var person = {                      //原型式繼承規(guī)范化為create()函數(shù)
    name: "Nicholas",
    friends: ["Shelby","Court","Van"]
};
var anotherPerson = Object.create(person, {
    name: {
        value: "Greg"
    }
});
c(anotherPerson.name);             //"Greg"
優(yōu)缺點(diǎn)

??如果想讓一個(gè)對(duì)象與另一個(gè)對(duì)象保持類似,原型式繼承是很貼切的,但是與原型模式一樣,包含引用類型的值得屬性會(huì)共享相應(yīng)的值。

5.寄生式繼承

寄生式繼承與原型式繼承緊密相關(guān)的一種思路,與寄生構(gòu)造函數(shù)和工廠模式類似,即創(chuàng)建一個(gè)僅用于封裝繼承過程的函數(shù),函數(shù)內(nèi)部以某種方式來增強(qiáng)對(duì)象,最后再像真的做了所有工作一樣返回對(duì)象。

舉個(gè)例子
function createAnother(original) { 
    var clone = object(original);          //此處用到了原型式繼承
    clone.sayHi = function() {
        c("Hi");
    };
    return clone;
}
var person = {                             //父類實(shí)例
    name: "Nicholas",
    friends: ["Shelby","Court","Van"]
};
var anotherPerson = createAnother(person);
anotherPerson.sayHi();

??上邊的寄生式繼承用到了原型式繼承,向?qū)崿F(xiàn)繼承的函數(shù)傳入一個(gè)父類對(duì)象實(shí)例,再用原型式繼承得到一個(gè)父類對(duì)象實(shí)例的副本,再給這個(gè)副本添加屬性,即增強(qiáng)這個(gè)對(duì)象,最后返回這個(gè)副本對(duì)象。由于用到了原型式繼承,這個(gè)對(duì)象的原型指向傳入的父類對(duì)象實(shí)例。上邊例子用到的object()函數(shù)(原型式繼承)并不是必須的,任何能夠返回新對(duì)象的函數(shù)都適用于寄生式繼承模式

優(yōu)缺點(diǎn)

??寄生式繼承在主要考慮對(duì)象而不是創(chuàng)建自定義類型和構(gòu)造函數(shù)時(shí),是十分有用的。但是如果考慮到用寄生式繼承為對(duì)象添加函數(shù)等,由于沒有用到原型,做不到函數(shù)復(fù)用,會(huì)導(dǎo)致效率降低。

6.寄生組合式繼承

??這個(gè)名字并不是很貼切,雖然叫寄生組合式繼承,但是和寄生式繼承關(guān)系不是很大,主要是用原型式繼承來實(shí)現(xiàn)原型屬性的繼承,用借用構(gòu)造函數(shù)模式繼承實(shí)例屬性。寄生組合式繼承和組合繼承的區(qū)別在于:

在繼承原型屬性時(shí),組合繼承用原型鏈繼承了整個(gè)父類(通過將父類實(shí)例賦值給子類構(gòu)造函數(shù)的原型對(duì)象來實(shí)現(xiàn)),這使子類中多了一份父類的實(shí)例屬性。而寄生組合式繼承用原型式繼承只繼承了父類的原型屬性(把父類構(gòu)造函數(shù)的原型對(duì)象用原型式繼承復(fù)制給子類的構(gòu)造函數(shù)的原型對(duì)象)。

組合繼承調(diào)用了兩次超類型構(gòu)造函數(shù),寄生組合式繼承調(diào)用了一次。

舉個(gè)例子
function inheritPrototype(subType, superType) {             //寄生式繼承
    var prototype = Object.create(superType.prototype);     //創(chuàng)建對(duì)象
    prototype.constructor = subType;                        //增強(qiáng)對(duì)象
    subType.prototype = prototype;                          //指定對(duì)象
}
function SuperType(name) {
    this.name = name;
    this.colors = ["red","blue","green"];
}
SuperType.prototype.sayName = function(){
    c(this.name);
};
function SubType(name, age) {
    SuperType.call(this, name);                 //借用構(gòu)造函數(shù)
    this.age = age;                             //添加子類獨(dú)有的屬性
}
inheritPrototype(SubType, SuperType);           //此處調(diào)用實(shí)現(xiàn)寄生組合繼承的函數(shù)
SubType.prototype.sayAge = function() {         //添加子類獨(dú)有原型屬性
    c(this.age);
};
var son = new SubType("erzi",16);
var father = new SuperType("baba");
c(typeof father.sayName);                       //function
c(typeof father.sayAge);                        //SubType獨(dú)有的方法,返回undefined
SubType.prototype.sayName = function() {        
    c("This function has be changed");          
}   
//更改子類的方法只會(huì)影響子類,prototype是對(duì)象,添加新屬性和更改屬性不會(huì)影響父類的prototype
father.sayName();                               //baba
son.sayName();                                  //This function has be changed
SuperType.prototype.sayName = function() {      //更改父類的原型屬性
    c("This function has be changed");
}
father.sayName();                               //This function has be changed
son.sayName();                                  //This function has be changed
優(yōu)缺點(diǎn)

??這種繼承方式理論上是完美的,但是由于出現(xiàn)的較晚,人們大多數(shù)使用的是組合繼承模式。

??以上就是我對(duì)于js繼承的一些理解,如有不足歡迎指出。

參考資料:《JavaScript高級(jí)程序設(shè)計(jì)》

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/83014.html

相關(guān)文章

  • JS理解繼承

    摘要:父類子類原理就是改變中的指向,指向的實(shí)例,子類會(huì)獲得父類的私有屬性和方法原型鏈繼承在中通過繼承到了父類的私有屬性和私有方法。子類私有繼承父類私有原理目前比較常用的是混合繼承和混合繼承,子類能很清晰的繼承父類的公有和私有。 前言:JS之理解原型和原型鏈,幾種常見的繼承方式介紹 1.call繼承,也叫借用構(gòu)造函數(shù)、偽造對(duì)象或是經(jīng)典繼承。call繼承回把父類的私有屬性和方法繼承給子類私有;...

    caiyongji 評(píng)論0 收藏0
  • 理解js原型與繼承

    摘要:相當(dāng)于在用原型繼承編寫復(fù)雜代碼前理解原型繼承模型十分重要。同時(shí),還要清楚代碼中原型鏈的長(zhǎng)度,并在必要時(shí)結(jié)束原型鏈,以避免可能存在的性能問題。 js是一門動(dòng)態(tài)語言,js沒有類的概念,ES6 新增了class 關(guān)鍵字,但只是語法糖,JavaScript 仍舊是基于原型。 至于繼承,js的繼承與java這種傳統(tǒng)的繼承不一樣.js是基于原型鏈的繼承. 在javascript里面,每個(gè)對(duì)象都有一...

    wthee 評(píng)論0 收藏0
  • JS理解ES6 繼承extends

    摘要:理解繼承在中對(duì)繼承有了更友好的方式。總的來說的的實(shí)質(zhì)和以前的繼承方式是一致的,但是有了更好的,更清晰的表現(xiàn)形式。 理解ES6繼承extends 1.在es6中對(duì)繼承有了更友好的方式。在下面的繼承中那到底在extends的時(shí)候做了什么,super()又是代表什么意思。 class People{ constructor(name, age) { this.name = name; ...

    starsfun 評(píng)論0 收藏0
  • JS中原型理解

    摘要:我們都知道在的世界中,幾乎所有東西都是對(duì)象,而對(duì)象又是通過繼承來層層獲得屬性和方法,首先我們要區(qū)分對(duì)象和構(gòu)造函數(shù)的區(qū)別,中對(duì)象繼承的是對(duì)象,函數(shù)繼承的是函數(shù)雖然函數(shù)也是對(duì)象,只有函數(shù)才有原型屬性供它實(shí)例的對(duì)象繼承,也就是說在中顯示如下字符串 我們都知道在JS的世界中,幾乎所有東西都是對(duì)象,而對(duì)象又是通過繼承來層層獲得屬性和方法, var str = new String(mario);...

    fxp 評(píng)論0 收藏0
  • javascript基礎(chǔ)篇:關(guān)于js面向?qū)ο?em>的理解

    摘要:關(guān)于中面向?qū)ο蟮睦斫饷嫦驅(qū)ο缶幊趟且环N編程思想我們的編程或者學(xué)習(xí)其實(shí)是按照類實(shí)例來完成的學(xué)習(xí)類的繼承封裝多態(tài)封裝把實(shí)現(xiàn)一個(gè)功能的代碼封裝到一個(gè)函數(shù)中一個(gè)類中以后再想實(shí)現(xiàn)這個(gè)功能,只需要執(zhí)行這個(gè)函數(shù)方法即可,不需要再重復(fù)的編寫代碼。 關(guān)于js中面向?qū)ο蟮睦斫?面向?qū)ο缶幊?oop) 它是一種編程思想 (object-oriented programming ), 我們的編程或者學(xué)習(xí)其...

    roadtogeek 評(píng)論0 收藏0
  • javascript基礎(chǔ)篇:關(guān)于js面向?qū)ο?em>的理解

    摘要:關(guān)于中面向?qū)ο蟮睦斫饷嫦驅(qū)ο缶幊趟且环N編程思想我們的編程或者學(xué)習(xí)其實(shí)是按照類實(shí)例來完成的學(xué)習(xí)類的繼承封裝多態(tài)封裝把實(shí)現(xiàn)一個(gè)功能的代碼封裝到一個(gè)函數(shù)中一個(gè)類中以后再想實(shí)現(xiàn)這個(gè)功能,只需要執(zhí)行這個(gè)函數(shù)方法即可,不需要再重復(fù)的編寫代碼。 關(guān)于js中面向?qū)ο蟮睦斫?面向?qū)ο缶幊?oop) 它是一種編程思想 (object-oriented programming ), 我們的編程或者學(xué)習(xí)其...

    newtrek 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<