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

資訊專欄INFORMATION COLUMN

「JavaScript」js中的繼承方法總結(jié)

Cristic / 1411人閱讀

摘要:缺點(diǎn)方法都在構(gòu)造函數(shù)中定義,每次創(chuàng)建實(shí)例都會(huì)創(chuàng)建一遍方法組合繼承組合繼承融合原型鏈繼承和構(gòu)造函數(shù)的優(yōu)點(diǎn),是中最常用的繼承模式然而組合繼承也有一個(gè)缺點(diǎn),就是會(huì)調(diào)用兩次父構(gòu)造函數(shù)。

1.前言

本文完整代碼指路我的GitHub,歡迎star。js中的繼承方式有很多種,以下僅列出部分。

2.原型鏈繼承

代碼如下:

function Parent() {
    this.name = "jchermy";
}

Parent.prototype.getName =  function() {
    console.log(this.name);
}

function Child() {

}

Child.prototype = new Parent();

var child1 = new Child();
console.log(child1.getName()); //jchermy

這樣看來貌似可以完美完成繼承,然后當(dāng)屬性換成引用類型時(shí),就會(huì)出現(xiàn)問題了,如下:

function Parent() {
    this.names = ["aa", "bb"]; //引用類型值
}

function Child() {

}

Child.prototype = new Parent();

var child1 = new Child();
child1.names.push("cc");
console.log(child1.names); //["aa","bb","cc"]

var child2 = new Child();
console.log(child2.names); //["aa","bb","cc"]

child2.names.push("dd");
console.log(child1.names) //["aa", "bb", "cc", "dd"]
console.log(child2.names);//["aa", "bb", "cc", "dd"]

var p = new Parent();
console.log(p.names); //["aa", "bb"]

由此我們可以得出原型鏈繼承的缺點(diǎn):

引用類型的屬性被所有實(shí)例共享

在創(chuàng)建Child實(shí)例時(shí),不能向Parent傳參

2.借用構(gòu)造函數(shù)繼承
function Parent() {
    this.names = ["aa", "bb"];
}

function Child() {
    Parent.call(this);
}

var child1 = new Child();
child1.names.push("cc");
console.log(child1.names);//["aa", "bb", "cc"]

var child2 = new Child();
console.log(child2.names);//["aa", "bb"]

child2.names.push("dd");
console.log(child1.names); //["aa", "bb", "cc"]
console.log(child2.names); //["aa", "bb", "dd"]

var p = new Parent();
p.names; //["aa", "bb"]

可以看出,借用構(gòu)造函數(shù)繼承避免了一下原型鏈繼承的問題,主要體現(xiàn)在:

避免了引用類型的屬性被所有實(shí)例共享

可以在Child中向Parent傳參

然而,借用構(gòu)造函數(shù)繼承也有缺點(diǎn)。

function Parent(name) {
    this.name = "parent "+name;
}

function Child(name) {
    this.name = "child"+name;
    Parent.call(this, name);
}

var child1 = new Child("hemin");
console.log(chil1.name); //"parent hemin"

var child2 = new Child("aa");
console.log(child2.name); //"parent aa"

缺點(diǎn):方法都在構(gòu)造函數(shù)中定義,每次創(chuàng)建實(shí)例都會(huì)創(chuàng)建一遍方法

3.組合繼承

組合繼承融合原型鏈繼承和構(gòu)造函數(shù)的優(yōu)點(diǎn),是JavaScript中最常用的繼承模式

function Parent(name) {
    this.name = name;
    this.colors = ["red", "blue"];
}

Parent.prototype.getName = function() {
    console.log(this.name);
}

function Child(name, age) {
    Parent.call(this, name); 
    this.age = age;
}

Child.prototype = new Parent();
Child.prototype.constructor = Child;

var child1 = new Child("aa", 18);
child1.colors.push("black");

child1.name; //"aa"
child1.age; //18
child1.colors; //["red", "blue","black"]

var child2 = new Child("bb", 20);
child2.name; //"bb"
child2.age; //20
child2.colors; //["red", "blue"]

然而組合繼承也有一個(gè)缺點(diǎn),就是會(huì)調(diào)用兩次父構(gòu)造函數(shù)。

如下:

Child.prototype = new Parent(); 
var child1 = new Child("aa", "18");

所以,在這個(gè)例子中,如果我們打印 child1 對(duì)象,我們會(huì)發(fā)現(xiàn) Child.prototype 和 child1 都有一個(gè)屬性為colors,屬性值為["red", "blue"]。

這個(gè)問題我們?cè)谙旅嬖儆懻摗?/p> 4.原型式繼承

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

var person = {
    name: "jchermy",
    friends: ["aa", "bb"]
}

var person1 = createObj(person);
var person2 = createObj(person);

//注意:修改person1.name的值,person2.name的值并未發(fā)生改變,
//并不是因?yàn)閜erson1和person2有獨(dú)立的 name 值,而是因?yàn)閜erson1.name = "person1",給person1添加了 name 值,并非修改了原型上的 name 值。
person1.name = "xiaomi";
console.log(person2.name); //"jchermy"

person2.friends.push("cc");
console.log(person1.friends); //["aa", "bb", "cc"]

缺點(diǎn):包含引用類型的屬性值始終會(huì)共享相應(yīng)的值,與原型鏈繼承一樣

5.寄生式繼承

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

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

var person = {
    name: "jchermy",
    friends: ["aa", "bb"]
};

var person1 = createObj(person);
var person2 = createObj(person);

person1.name = "xiaomi";
console.log(person1.name); //"xiaomi"
console.log(person2.name); //"jchermy"

person1.friends.push("xxx");
console.log(person1.friends); // ["aa", "bb", "xxx"]
console.log(person2.friends); // ["aa", "bb", "xxx"]

缺點(diǎn):

跟借用構(gòu)造函數(shù)模式一樣,每次創(chuàng)建對(duì)象都會(huì)創(chuàng)建一遍方法

包含引用類型的屬性值始終會(huì)共享相應(yīng)的值

6.寄生組合式繼承

還記得組合繼承中提到的那些問題嗎,那么我們?cè)撊绾尉媲缶苊膺@一次重復(fù)調(diào)用呢?

如果我們不使用 Child.prototype = new Parent() ,而是間接的讓 Child.prototype 訪問到 Parent.prototype 呢?可以這樣實(shí)現(xiàn):

function Parent(name) {
   this.name = name;
   this.colors = ["red", "blue", "green"];
}

Parent.prototype.getName = function () {
    console.log(this.name);
  }

  function Child(name, age) {
      Parent.call(this, name);
      this.age = age;
  }

//關(guān)鍵的三步
  var F = function(){};

  F.prototype = Parent.prototype;

  Child.prototype = new F();


  
  Child.prototype.constructor = Child;

  var child1 = new Child("xiaomi", 18);
  var child2 = new Child2("aa", 24);
  console.log(child1.name); //xiaomi
  console.log(child2.name); //aa

  child1.colors.push("black");
  child1.colors; //["red", "blue", "green", "black"]
  child2.colors; //["red", "blue", "green"];
這種方式的高效率體現(xiàn)它只調(diào)用了一次 Parent 構(gòu)造函數(shù),并且因此避免了在 Parent.prototype 上面創(chuàng)建不必要的、多余的屬性。與此同時(shí),原型鏈還能保持不變;因此,還能夠正常使用 instanceof 和 isPrototypeOf。開發(fā)人員普遍認(rèn)為寄生組合式繼承是引用類型最理想的繼承范式。
7.結(jié)語

如果文章對(duì)你有幫助的話,歡迎點(diǎn)贊收藏!!有錯(cuò)誤和不合理的地方歡迎大家指正!GitHub給個(gè)star就最好啦!=(//▽//)感謝大家~

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

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

相關(guān)文章

  • [原創(chuàng)] JavaScript中的繼承總結(jié)

    摘要:中繼承比較復(fù)雜,坑比較多,最近有點(diǎn)時(shí)間整理下,記錄下來。的繼承實(shí)現(xiàn)方式大概分類如下的兩大類,每一種實(shí)現(xiàn)都有自己的有點(diǎn)和缺點(diǎn),根據(jù)場(chǎng)景選擇吧通過修改原型鏈來來實(shí)現(xiàn)繼承通過復(fù)制父類來來實(shí)現(xiàn)繼承為了理解繼承的原型鏈的變化,我畫了原型鏈圖。 JS 中繼承比較復(fù)雜,坑比較多,最近有點(diǎn)時(shí)間整理下,記錄下來。 JS 的繼承實(shí)現(xiàn)方式大概分類如下的兩大類,每一種實(shí)現(xiàn)都有自己的有點(diǎn)和缺點(diǎn),根據(jù)場(chǎng)景選擇吧 ...

    sixgo 評(píng)論0 收藏0
  • JS程序

    摘要:設(shè)計(jì)模式是以面向?qū)ο缶幊虨榛A(chǔ)的,的面向?qū)ο缶幊毯蛡鹘y(tǒng)的的面向?qū)ο缶幊逃行┎顒e,這讓我一開始接觸的時(shí)候感到十分痛苦,但是這只能靠自己慢慢積累慢慢思考。想繼續(xù)了解設(shè)計(jì)模式必須要先搞懂面向?qū)ο缶幊蹋駝t只會(huì)讓你自己更痛苦。 JavaScript 中的構(gòu)造函數(shù) 學(xué)習(xí)總結(jié)。知識(shí)只有分享才有存在的意義。 是時(shí)候替換你的 for 循環(huán)大法了~ 《小分享》JavaScript中數(shù)組的那些迭代方法~ ...

    melody_lql 評(píng)論0 收藏0
  • JavaScript知識(shí)點(diǎn)總結(jié)

    摘要:參與任何數(shù)值計(jì)算的結(jié)構(gòu)都是,而且。。面向人類的理性事物,而不是機(jī)器信號(hào)。達(dá)到無刷新效果。的工作原理總是指向一個(gè)對(duì)象,具體是運(yùn)行時(shí)基于函數(shù)的執(zhí)行環(huán)境動(dòng)態(tài)綁定的,而非函數(shù)被聲明時(shí)的環(huán)境。原型對(duì)象上有一個(gè)屬性,該屬性指向的就是構(gòu)造函數(shù)。 1.JS面向?qū)ο蟮睦斫?面向?qū)ο蟮娜筇攸c(diǎn):繼承、封裝、多態(tài) 1、JS中通過prototype實(shí)現(xiàn)原型繼承 2、JS對(duì)象可以通過對(duì)象冒充,實(shí)現(xiàn)多重繼承, 3...

    sean 評(píng)論0 收藏0
  • JavasScript重難點(diǎn)知識(shí)

    摘要:忍者級(jí)別的函數(shù)操作對(duì)于什么是匿名函數(shù),這里就不做過多介紹了。我們需要知道的是,對(duì)于而言,匿名函數(shù)是一個(gè)很重要且具有邏輯性的特性。通常,匿名函數(shù)的使用情況是創(chuàng)建一個(gè)供以后使用的函數(shù)。 JS 中的遞歸 遞歸, 遞歸基礎(chǔ), 斐波那契數(shù)列, 使用遞歸方式深拷貝, 自定義事件添加 這一次,徹底弄懂 JavaScript 執(zhí)行機(jī)制 本文的目的就是要保證你徹底弄懂javascript的執(zhí)行機(jī)制,如果...

    forsigner 評(píng)論0 收藏0
  • 前端文檔收集

    摘要:系列種優(yōu)化頁面加載速度的方法隨筆分類中個(gè)最重要的技術(shù)點(diǎn)常用整理網(wǎng)頁性能管理詳解離線緩存簡(jiǎn)介系列編寫高性能有趣的原生數(shù)組函數(shù)數(shù)據(jù)訪問性能優(yōu)化方案實(shí)現(xiàn)的大排序算法一怪對(duì)象常用方法函數(shù)收集數(shù)組的操作面向?qū)ο蠛驮屠^承中關(guān)鍵詞的優(yōu)雅解釋淺談系列 H5系列 10種優(yōu)化頁面加載速度的方法 隨筆分類 - HTML5 HTML5中40個(gè)最重要的技術(shù)點(diǎn) 常用meta整理 網(wǎng)頁性能管理詳解 HTML5 ...

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

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

0條評(píng)論

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