最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JavaScript中六種面試常考繼承方式總結(jié)

 更新時間:2023年02月13日 09:14:59   作者:mick  
js的幾種繼承方式在我們面試的時候經(jīng)常會被問到,所以深入理解js幾種繼承方式以及它們的優(yōu)缺點(diǎn)是非常有必要的。本文為大家整理了JavaScript中面試常考的六種繼承方式,需要的可以參考一下

js的幾種繼承方式在我們面試的時候經(jīng)常會被問到,所以深入理解js幾種繼承方式以及它們的優(yōu)缺點(diǎn)是非常有必要的。

原型鏈繼承

之前我們介紹過原型和實例的關(guān)系:每一個構(gòu)造函數(shù)都有一個原型prototype,原型對象中的constructor又指回構(gòu)造函數(shù),實例中有一個內(nèi)部指針__proto__指向構(gòu)造函數(shù)的prototype。不清楚的可以看這篇 下面看個代碼

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

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

function Child() {}

Child.prototype = new Parent();

var child1 = new Child();

console.log(child1.getName());

我們將構(gòu)造函數(shù)Parent的實例賦值給了構(gòu)造函數(shù)Child的原型,實現(xiàn)了Child能夠繼承Parent的屬性和方法。

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

1.父類的方法可以被復(fù)用

缺點(diǎn)

1.父類的所有屬性都會被子類共享,只要修改了一個子類的引用類型的屬性,其他的子類也會受影響

function Parent() {
  this.names = ["mick", "randy"];
}

function Child() {}

Child.prototype = new Parent();

var child1 = new Child();

child1.names.push("qr");

console.log(child1.names); // ["mick", "randy", "qr"]

var child2 = new Child();

console.log(child2.names); //  ["mick", "randy", "qr"]

2.子類實例不能給父類構(gòu)造函數(shù)傳參

盜用構(gòu)造函數(shù)

盜用構(gòu)造函數(shù)的思路其實就是在子類構(gòu)造函數(shù)中通過call或者apply方法調(diào)用父類構(gòu)造函數(shù)

function Parent() {
  this.names = ["mick", "randy"];
}

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

var child1 = new Child();

child1.names.push("qr");

console.log(child1.names); // ["mick", "randy", "qr"]

var child2 = new Child();

console.log(child2.names); //  ["mick", "randy"]

這里我們通過在構(gòu)造函數(shù)Child中通過call調(diào)用Parent,此時this就是構(gòu)造函數(shù)Child,其實就是Child的實例被創(chuàng)建的時候都會對Parent進(jìn)行初始化,相當(dāng)于每一個實例都擁有了names屬性。

我們也可以給父構(gòu)造函數(shù)傳參了

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

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

var child1 = new Child("randy", 18);

console.log(child1.name); // randy

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

  • 可以在子類構(gòu)造函數(shù)向父類構(gòu)造函數(shù)傳參
  • 父類的實例的引用屬性不會被共享

缺點(diǎn)

子類不能訪問父類原型上的方法,所以所有方法和屬性都寫在構(gòu)造函數(shù)中,每次實例創(chuàng)建都會被初始化。

組合繼承

組合繼承就是綜合原型鏈繼承和盜用構(gòu)造函數(shù)繼承的優(yōu)點(diǎn),從何又對這兩種方法的缺點(diǎn)互補(bǔ)。使用原型鏈繼承可以訪問父類原型上的屬性和方法,通過構(gòu)造函數(shù)繼承可以訪父類實例的屬性和方法。

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;
}

Child.prototype = new Parent(); // 第二次
Child.prototype.constructor = Child;

var child1 = new Child("mick", "18");

child1.colors.push("black");

console.log(child1.name); // mick
console.log(child1.age); // 18
console.log(child1.colors); // ["red", "blue", "green", "black"]

var child2 = new Child("randy", "20");

console.log(child2.name); // randy
console.log(child2.age); // 20
console.log(child2.colors); // ["red", "blue", "green"]

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

  • 父類的方法可以復(fù)用
  • 可以在子類構(gòu)造函數(shù)向父類傳參
  • 父類構(gòu)造函數(shù)中的引用屬性不會共享

缺點(diǎn)

父類構(gòu)造函數(shù)被調(diào)用了兩次(文章中的注釋已經(jīng)標(biāo)出)

原型式繼承

創(chuàng)建一個臨時的構(gòu)造函數(shù),將傳入的對象賦值給這個構(gòu)造函數(shù)的原型,然后返回這個臨時類型的一個實例。其實就是對傳入對應(yīng)進(jìn)行一次淺復(fù)制。

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

其實就是Object.create的模擬實現(xiàn),將傳入的對象作為創(chuàng)建的對象的原型 缺點(diǎn)

1.引用類型的屬性值始終都會共享相應(yīng)的值,這點(diǎn)跟原型鏈繼承一樣

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

let person = {
  name: "mick",
  colors: ["red", "blue", "green"],
};

let anotherPerson = createObj(person);
anotherPerson.name = "randy";
anotherPerson.colors.push("black");
console.log(anotherPerson.colors); // ['red', 'blue', 'green', 'black']
let yetAnotherPerson = createObj(person);

yetAnotherPerson.colors.push("yellow");
console.log(yetAnotherPerson.name); // mick
console.log(yetAnotherPerson.colors); // ['red', 'blue', 'green', 'black', 'yellow']

修改了anotherPerson.name的值,yetAnotherPerson.name沒有發(fā)生變化,這是因為anotherPerson.nameanotherPerson添加了name的值,并不是修改了原型上的值。

寄生式繼承

寄生式繼承背后類似于寄生構(gòu)造函數(shù)和工廠模式:創(chuàng)建一個實現(xiàn)繼承的函數(shù),以某種方式增強(qiáng)對象,然后返回這個對象。我們繼續(xù)使用原型式繼承創(chuàng)建的方法

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

function createAnother(original) {
  let clone = createObj(original);
  clone.sayHi = function () {
    console.log("hi");
  };
  return clone;
}

缺點(diǎn)

跟盜用構(gòu)造函數(shù)一樣的,方法在每次創(chuàng)建對象都會重新創(chuàng)建一遍

寄生式組合繼承

我們首先回看下組合繼承有個缺點(diǎn)就是父類構(gòu)造函數(shù)會調(diào)用兩次,那如何優(yōu)化這個缺點(diǎn)呢?

寄生式組合繼承通過盜用構(gòu)造函數(shù)繼承屬性,但使用混合式原型鏈繼承方法。基本思路是不通過調(diào)用父類構(gòu)造函數(shù)給子類原型賦值,而是取得父類原型的一個副本。也就是使用寄生式繼承來繼承父類原型,然后將返回的新對象賦值給子類原型

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;
}

var F = function () {};
F.prototype = Parent.prototype;
Child.prototype = new F();

var child1 = new Child("mick", "18");

console.log(child1);

封裝一下

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

function prototype(child, Parent) {
  var prototype = createObj(parent.prototype);
  prototype.constructor = child;
  child.prototype = prototype;
}
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;
}

prototype(Child, Parent)

var child1 = new Child("mick", "18");

console.log(child1);

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

以上就是JavaScript中六種面試??祭^承方式總結(jié)的詳細(xì)內(nèi)容,更多關(guān)于JavaScript繼承方式的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 利用策略模式與裝飾模式擴(kuò)展JavaScript表單驗證功能

    利用策略模式與裝飾模式擴(kuò)展JavaScript表單驗證功能

    這篇文章主要介紹了利用策略模式與裝飾模式擴(kuò)展JavaScript表單驗證功能,需要的朋友可以參考下
    2017-02-02
  • Bootstrap Chart組件使用教程

    Bootstrap Chart組件使用教程

    圖表組件Chart.js是Bootstrap比較好用的組件之一,與一款收費(fèi)的組件highchart類似,效果上來看免費(fèi)與收費(fèi)的產(chǎn)品相差還是有一點(diǎn)點(diǎn)的,不過功能上差不多能滿足我們項目的需要,本文給大家介紹Bootstrap Chart組件使用,需要的朋友參考下吧
    2016-04-04
  • js實現(xiàn)磚頭在頁面拖拉效果

    js實現(xiàn)磚頭在頁面拖拉效果

    這篇文章主要為大家詳細(xì)介紹了js實現(xiàn)磚頭在頁面拖拉效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • JS實現(xiàn)的3D拖拽翻頁效果代碼

    JS實現(xiàn)的3D拖拽翻頁效果代碼

    這篇文章主要介紹了JS實現(xiàn)的3D拖拽翻頁效果,通過鼠標(biāo)事件結(jié)合時間函數(shù)動態(tài)操作頁面元素實現(xiàn)拖拽翻頁的效果,需要的朋友可以參考下
    2015-10-10
  • 基于JavaScript簡單實現(xiàn)一下新手引導(dǎo)效果

    基于JavaScript簡單實現(xiàn)一下新手引導(dǎo)效果

    這篇文章主要為大家詳細(xì)介紹了如何基于JavaScript簡單實現(xiàn)一下新手引導(dǎo)效果,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-03-03
  • 淺析JS原始值和引用值問題

    淺析JS原始值和引用值問題

    如果一個值是引用類型的,那么它的存儲空間將從堆中分配。由于引用值的大小會改變,所以不能把它放在棧中,否則會降低變量查尋的速度。相反,放在變量的??臻g中的值是該對象存儲在堆中的地址,這篇文章主要介紹了JS原始值和引用值 ,需要的朋友可以參考下
    2021-12-12
  • 基于javascript原生判斷DOM是否加載完畢

    基于javascript原生判斷DOM是否加載完畢

    這篇文章主要介紹了基于javascript原生判斷DOM是否加載完畢,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-10-10
  • javascript制作游戲開發(fā)碰撞檢測的封裝代碼

    javascript制作游戲開發(fā)碰撞檢測的封裝代碼

    這篇文章主要介紹了javascript制作游戲開發(fā)碰撞檢測的封裝代碼,需要的朋友可以參考下
    2015-03-03
  • Bootstrap 輪播(Carousel)插件

    Bootstrap 輪播(Carousel)插件

    Bootstrap 輪播(Carousel)插件是一種靈活的響應(yīng)式的向站點(diǎn)添加滑塊的方式。下面通過本文給大家介紹Bootstrap 輪播(Carousel)插件,非常不錯,需要的朋友參考下吧
    2016-12-12
  • js+div實現(xiàn)圖片滾動效果代碼

    js+div實現(xiàn)圖片滾動效果代碼

    本篇文章主要是對js+div實現(xiàn)圖片滾動效果的示例代碼進(jìn)行了介紹,需要的朋友可以過來參考下,希望對大家有所幫助
    2014-02-02

最新評論

电白县| 商丘市| 盐池县| 勐海县| 延津县| 盐津县| 刚察县| 普兰店市| 甘谷县| 静宁县| 尼勒克县| 中西区| 左权县| 互助| 济南市| 南汇区| 黄石市| 通榆县| 迭部县| 济阳县| 武义县| 旬邑县| 金华市| 石屏县| 大兴区| 洛南县| 板桥市| 黑龙江省| 巩义市| 泰顺县| 巫山县| 光泽县| 通榆县| 恩平市| 镇平县| 谷城县| 朝阳县| 德清县| 静安区| 镇远县| 巴塘县|