成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

js各種方法繼承以及優(yōu)缺點(diǎn)

Cristalven / 557人閱讀

摘要:的屬性是指向的,繼承的屬性在寄生式繼承創(chuàng)建一個(gè)僅用于封裝繼承過(guò)程的函數(shù),該函數(shù)在內(nèi)部以某種形式來(lái)做增強(qiáng)對(duì)象,最后返回對(duì)象。缺點(diǎn)跟構(gòu)造函數(shù)模式一樣,每次創(chuàng)建對(duì)象都會(huì)創(chuàng)建一遍方法。

前言

上文講到j(luò)s中的原型鏈,這篇文章對(duì)每種繼承方式具體分析一下

原型鏈繼承

原型鏈繼承就是將父類(lèi)的實(shí)例賦給子類(lèi)的原型對(duì)象,話(huà)不多說(shuō),看下代碼

function parent(name){
    this.name = "111";
}
parent.prototype.getName = function(){
    console.log(this.name)
}
function child(){}
child.prototype = new parent();
const child1 = new child()
child1.getName();//111
console.log(child.name);//111

優(yōu)點(diǎn): 可以直接繼承父類(lèi)的屬性和方法,這里的屬性繼承是通過(guò)__proto__找到的,不是實(shí)例本身?yè)碛械?br>缺點(diǎn): 1.不能向父類(lèi)傳參 2.引用屬性會(huì)被所有實(shí)例共享

function parent(){
    this.name = ["111","2222"]
}
parent.prototype.getName = function(){
    console.log(this.name)
}
function child(){}
child.prototype = new parent();
const child1 = new child();
const child2 = new child();
child1.name.push("aaa")
console.log(child1.name,child2.name)//["111","2222","aaa"]

3.child的constructor指向parent,應(yīng)該予以修復(fù)

child.prototype.constructor = child;
構(gòu)造函數(shù)繼承

構(gòu)造函數(shù)繼承就是在子類(lèi)調(diào)用父類(lèi),看代碼

function parent(name){
    this.name = name;
}
function child(name){
   parent.call(this,name);
}
const child1 = new child("child");
console.log(child1.name)//child

優(yōu)點(diǎn):可以繼承父類(lèi)的屬性(這里的屬性繼承是實(shí)例本身自己的),可以向父類(lèi)傳參,引用類(lèi)型不會(huì)被所有實(shí)例共享,constructor還是指向自己child
缺點(diǎn):不能繼承父類(lèi)原型上的方法,方法都在構(gòu)造函數(shù)中定義,每次創(chuàng)建實(shí)例都會(huì)創(chuàng)建一遍方法。

function parent(name){
    this.name = name;
    this.arr = ["111"]
}
function child(name){
   parent.call(this,name);
}
const child1 = new child("child1");
const child2 = new child("child2")
child1.arr.push("222");
console.log(child1.arr,child2.arr)//(2)?["111", "222"] ["111"]
組合繼承

如果結(jié)合原型繼承和構(gòu)造函數(shù)繼承,這樣就可以結(jié)合其優(yōu)點(diǎn),摒棄其缺點(diǎn)了,這就是組合繼承

function parent(name){
   this.name = name;
   this.arr = ["111"]
}
parent.prototype.getName = function(){
   console.log(this.name)
}
function child(name){
    parent.call(this,name)
}
child.prototype = new parent();
const child1 = new child("child1");
const child2 = new child("child2");
child1.arr.push("222");
child1.getName();//child1
console.log(child1.arr,child2.arr)//2)?["111", "222"] ["111"]

優(yōu)點(diǎn): 可以向父類(lèi)傳參,可以繼承父類(lèi)的屬性(子類(lèi)會(huì)有從父類(lèi)繼承的屬性,__proto__上基本屬性是undefined,引用屬性是有的,看下圖)和原型上的方法,引用屬性不會(huì)被共享

缺點(diǎn): 一個(gè)實(shí)例會(huì)實(shí)例化父類(lèi)兩次,parent.call(this,name)調(diào)用一次,child.prototype = new parent()調(diào)用一次,constructor指向了parent

原型繼承
function create(o){
   function F(){};
   F.prototype = o;
   return new F();
}

原型繼承其實(shí)就是es5的object.create()的實(shí)現(xiàn)
看下這段代碼

const person = {
   name: "name",
   arr: ["111","222"]
}
const p1 = create(person);
const p2 = create(person);
p1.name = "p1";
p1.arr.push("aaa");
console.log(p1.name,p2.name);//p1,name
console.log(p1.arr,p2.arr);//(3)?["111", "222", "aaa"] (3)?["111", "222", "aaa"]

缺點(diǎn):會(huì)共享引用屬性
注意:修改p1.name的值,p2.name的值并未發(fā)生改變,并不是因?yàn)閜1和p2有獨(dú)立的 name 值,而是因?yàn)閜1.name = "p1",給person1添加了 name 值,并非修改了原型上的 name 值。p1,p2的constructor屬性是指向object的,繼承的屬性在__proto__

寄生式繼承

創(chuàng)建一個(gè)僅用于封裝繼承過(guò)程的函數(shù),該函數(shù)在內(nèi)部以某種形式來(lái)做增強(qiáng)對(duì)象,最后返回對(duì)象。

function createObj (o) {
  var clone = object.create(o);
  clone.sayName = function () {
    console.log("hi");
  }
  return clone;
}

缺點(diǎn):跟構(gòu)造函數(shù)模式一樣,每次創(chuàng)建對(duì)象都會(huì)創(chuàng)建一遍方法。

寄生組合式繼承

終極繼承??!寄生組合式繼承,結(jié)合了以上的優(yōu)點(diǎn),來(lái)看下代碼
組合繼承的缺點(diǎn)就是會(huì)調(diào)用兩次父類(lèi),如何避免調(diào)用兩次呢?能不能直接讓子類(lèi)的prototype訪(fǎng)問(wèn)到父類(lèi)的prototype?當(dāng)然可以??!看下面的代碼

function parent(name){
   this.name = name;
   this.arr = ["111"]
}
parent.prototype.getName = function(){
   console.log(this.name)
}
function child(name){
    parent.call(this,name)
}
//注意!!關(guān)鍵!!
function F(){}
F.prototype = parent.prototype;
child.prototype = new F();

const c1 = new child("c1");
const c2 = new child("c2");
c1.arr.push("ccc");
c1.name = "name";
c1.getName();//name
c2.getName();//c2
console.log(c1,c2);//child?{name: "name", arr: Array(2)} child?{name: "c2", arr: Array(1)}

優(yōu)點(diǎn):可以繼承父類(lèi)的屬性和原型上的方法,實(shí)例間不會(huì)共享引用屬性,基本屬性也可以繼承變成自己的屬性,不會(huì)執(zhí)行兩遍父類(lèi)

缺點(diǎn): 子類(lèi)的constructor指向指向了父類(lèi),應(yīng)該修復(fù)之,可以改寫(xiě)如下
可以改寫(xiě)寫(xiě)上面的關(guān)鍵步驟

function create(o){
   function F(){}
   F.prototype = o;
   return new F();
}
function prototype(child,parent){
   const p = create(parent.prototype);
   p.constructor = child;
   child.prototype = p;
}

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/108306.html

相關(guān)文章

  • 深入理解JavaScript

    摘要:深入之繼承的多種方式和優(yōu)缺點(diǎn)深入系列第十五篇,講解各種繼承方式和優(yōu)缺點(diǎn)。對(duì)于解釋型語(yǔ)言例如來(lái)說(shuō),通過(guò)詞法分析語(yǔ)法分析語(yǔ)法樹(shù),就可以開(kāi)始解釋執(zhí)行了。 JavaScript深入之繼承的多種方式和優(yōu)缺點(diǎn) JavaScript深入系列第十五篇,講解JavaScript各種繼承方式和優(yōu)缺點(diǎn)。 寫(xiě)在前面 本文講解JavaScript各種繼承方式和優(yōu)缺點(diǎn)。 但是注意: 這篇文章更像是筆記,哎,再讓我...

    myeveryheart 評(píng)論0 收藏0
  • js繼承從入門(mén)到理解

    摘要:?jiǎn)栴}修改實(shí)例的,即修改了構(gòu)造函數(shù)的原型對(duì)象的共享屬性到此處,涉及到的內(nèi)容大家可以再回頭捋一遍,理解了就會(huì)覺(jué)得醍醐灌頂。 開(kāi)場(chǎng)白 大三下學(xué)期結(jié)束時(shí)候,一個(gè)人跑到帝都來(lái)參加各廠(chǎng)的面試,免不了的面試過(guò)程中經(jīng)常被問(wèn)到的問(wèn)題就是JS中如何實(shí)現(xiàn)繼承,當(dāng)時(shí)的自己也是背熟了實(shí)現(xiàn)繼承的各種方法,回過(guò)頭來(lái)想想?yún)s不知道__proto__是什么,prototype是什么,以及各種繼承方法的優(yōu)點(diǎn)和缺點(diǎn),想必有好...

    不知名網(wǎng)友 評(píng)論0 收藏0
  • javascript 中各種繼承方式的優(yōu)缺點(diǎn)

    摘要:中實(shí)現(xiàn)繼承的方式有很多種,一般都是通過(guò)原型鏈和構(gòu)造函數(shù)來(lái)實(shí)現(xiàn)。下面對(duì)各種實(shí)現(xiàn)方式進(jìn)行分析,總結(jié)各自的優(yōu)缺點(diǎn)。一原型繼承通過(guò)改變?cè)蛯?duì)象實(shí)現(xiàn)繼承保持構(gòu)造函數(shù)和原型對(duì)象的完整性說(shuō)明是繼承而來(lái)的屬性復(fù)用了方法優(yōu)點(diǎn)父類(lèi)的方法得到了復(fù)用。 javascript中實(shí)現(xiàn)繼承的方式有很多種,一般都是通過(guò)原型鏈和構(gòu)造函數(shù)來(lái)實(shí)現(xiàn)。下面對(duì)各種實(shí)現(xiàn)方式進(jìn)行分析,總結(jié)各自的優(yōu)缺點(diǎn)。 一 原型繼承 let Sup...

    desdik 評(píng)論0 收藏0
  • js中對(duì)數(shù)據(jù)類(lèi)型的總結(jié)及判斷數(shù)據(jù)類(lèi)型的各種方法優(yōu)缺點(diǎn)

    摘要:最常見(jiàn)的判斷方法它的官方解釋操作符返回一個(gè)字符串,表示未經(jīng)計(jì)算的操作數(shù)的類(lèi)型。另外,是判斷對(duì)象是否屬于某一類(lèi)型,而不是獲取的對(duì)象的類(lèi)型。多個(gè)窗口意味著多個(gè)全局環(huán)境,不同的全局環(huán)境擁有不同的全局對(duì)象,從而擁有不同的內(nèi)置類(lèi)型構(gòu)造函數(shù)。 js中的數(shù)據(jù)類(lèi)型 js中只有六種原始數(shù)據(jù)類(lèi)型和一個(gè)Object: Boolean Null Undefined Number String Symbol ...

    voyagelab 評(píng)論0 收藏0
  • JavaScript之深入各種繼承

    摘要:通常有這兩種繼承方式接口繼承和實(shí)現(xiàn)繼承。理解繼承的工作是通過(guò)調(diào)用函數(shù)實(shí)現(xiàn)的,所以是寄生,將繼承工作寄托給別人做,自己只是做增強(qiáng)工作。適用基于某個(gè)對(duì)象或某些信息來(lái)創(chuàng)建對(duì)象,而不考慮自定義類(lèi)型和構(gòu)造函數(shù)。 一、繼承的概念 繼承,是面向?qū)ο笳Z(yǔ)言的一個(gè)重要概念。通常有這兩種繼承方式:接口繼承和實(shí)現(xiàn)繼承。接口繼承只繼承方法簽名,而實(shí)現(xiàn)繼承則繼承實(shí)際的方法。 《JS高程》里提到:由于函數(shù)沒(méi)有簽名,...

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

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

0條評(píng)論

閱讀需要支付1元查看
<