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

資訊專(zhuān)欄INFORMATION COLUMN

JavaScript常用的繼承方式

zhangfaliang / 3245人閱讀

摘要:常用繼承方式主要分為種原型鏈繼承構(gòu)造函數(shù)繼承組合繼承原型式繼承寄生式繼承寄生組合繼承以及繼承多個(gè)對(duì)象。所以說(shuō),構(gòu)造函數(shù)基礎(chǔ)只能繼承父類(lèi)的實(shí)例屬性和方法,不能繼承原型鏈上的屬性和方法。

JavaScript常用繼承方式主要分為(7種):原型鏈繼承、構(gòu)造函數(shù)繼承、組合繼承、原型式繼承、寄生式繼承、寄生組合繼承以及繼承多個(gè)對(duì)象。

1:原型鏈繼承(核心:將父類(lèi)的實(shí)例作為子類(lèi)的原型)

基本概念:重寫(xiě)原型對(duì)象,賦予一個(gè)新的對(duì)象的實(shí)例?;舅枷刖褪亲屢粋€(gè)原型對(duì)象指向另一個(gè)父類(lèi)的實(shí)例。

function Super() {
    //基本數(shù)據(jù)類(lèi)型
    this.text = "Hello";
}
Super.prototype.getSuperText = function() {
    return this.text;
}
function Sub() {
    this.subText = "Word";
}

Sub.prototype = new Super();

const instance = new Sub();
console.log(instance);

特點(diǎn):非常純粹的繼承關(guān)系,實(shí)例是子類(lèi)的實(shí)例,也是父類(lèi)的實(shí)例。父類(lèi)新增原型方法或?qū)傩?,子?lèi)都能訪問(wèn)到。

優(yōu)點(diǎn):簡(jiǎn)單易于操作

缺點(diǎn):對(duì)引用類(lèi)型數(shù)據(jù)操作會(huì)互相(多個(gè)實(shí)例之間)影響

function Super() {
    //復(fù)雜對(duì)象,也就是引用類(lèi)型
    this.value = [1, 2, 3, 4];
}
Super.prototype.getSuperValue = function() {
    return this.value;
}
function Sub() {
    this.subText = "Word";
}

Sub.prototype = new Super();

const instance1 = new Sub();
const instance2 = new Sub();

instance1.value.push(5);
console.log(instance2.value);

// (5)?[1, 2, 3, 4, 5]
2:構(gòu)造函數(shù)繼承
//定義構(gòu)造函數(shù)
function Super(){
    this.value = [1, 2, 3, 4];
}
//新增屬性getSuperValue
Super.prototype.getSuperValue = function() {
    return this.value;
}
//sub每次執(zhí)行都要重新調(diào)用
function Sub(){
    Super.call(this);
}

const instance1 = new Sub();
instance1.value.push(5);
console.log(instance1.value);
// (5)?[1, 2, 3, 4, 5]

const instance2 = new Sub();
console.log(instance2.value);
// (4)?[1, 2, 3, 4]

構(gòu)造函數(shù)的特點(diǎn):(對(duì)引用數(shù)據(jù)類(lèi)型沒(méi)有影響)上面的代碼輸出instance1是1,2,3,4,5,instance2是1,2,3,4。這是因?yàn)閟ub每次在執(zhí)行時(shí)都是重新調(diào)用了一個(gè)super.call(),而且構(gòu)造函數(shù)在構(gòu)建對(duì)象的過(guò)程中,每次都是創(chuàng)建了一個(gè)新的object,因此每次調(diào)用sub都會(huì)執(zhí)行一遍super,每次執(zhí)行時(shí)都會(huì)有申請(qǐng)一個(gè)新的內(nèi)存空間,所以得到的兩個(gè)value值是不一樣互不影響的。

缺點(diǎn):在整個(gè)構(gòu)造函數(shù)的基礎(chǔ)過(guò)程中,上面的代碼并沒(méi)有使用proto和prototype的屬性,沒(méi)有使用的話那么原型鏈就沒(méi)有接上。所以說(shuō),構(gòu)造函數(shù)基礎(chǔ)只能繼承父類(lèi)的實(shí)例屬性和方法,不能繼承原型鏈上的屬性和方法。

3:組合繼承

通過(guò)調(diào)用父類(lèi)構(gòu)造,繼承父類(lèi)的屬性并保留傳參的優(yōu)點(diǎn),然后通過(guò)將父類(lèi)實(shí)例作為子類(lèi)原型,實(shí)現(xiàn)函數(shù)復(fù)用。

保留了構(gòu)造函數(shù)繼承與原型鏈繼承的優(yōu)點(diǎn)。但是執(zhí)行了兩次Person,屬性重復(fù)了。

function Person(name) {
    this.name = name;
    this.value = ["head", "body", "legs"];
}
Person.prototype.getName = function() {
    return this.name;
};

// 構(gòu)造函數(shù)繼承
function Teacher(name, school){
    // 執(zhí)行又一次Person
    Person.call(this, name);
    this.school = school;
}

// 原型鏈繼承
// 執(zhí)行一次Person
Teacher.prototype = new Person(); 
const Eric = new Teacher("Eric",27);
Eric.getName();
// 輸出:Eric



// prototype構(gòu)造器指回自己 
Teacher.prototype.constructor = Teacher;

Teacher.prototype.getSchool = function() {
    return this.school;
};

特點(diǎn):既可以繼承實(shí)例屬性和方法,也可以繼承原型屬性和方法。既是子類(lèi)的實(shí)例也是父類(lèi)的實(shí)例,不存在引用屬性共享的問(wèn)題??梢詡鲄ⅲ瘮?shù)可復(fù)用。

缺點(diǎn):調(diào)用兩次父類(lèi)構(gòu)造函數(shù),生成了兩份實(shí)例。

4:原型式繼承

借助原型可以基于已有的對(duì)象創(chuàng)建新的對(duì)象,同時(shí)還不必因此創(chuàng)建自定義類(lèi)型。

原理:(本質(zhì))利用一個(gè)空對(duì)象作為一個(gè)中介。

const lakers = {
    name: "lakers",
    value: ["Micheal", "Wade", "Kobe"]
};

const lakers1 = Object.create(lakers);
const lakers2 = Object.create(lakers);

lakers1.value.push("Fish");
console.log(lakers);

模擬Object.create()

object.create()原理:用一個(gè)函數(shù)包裝一個(gè)對(duì)象,然后返回這個(gè)函數(shù)的調(diào)用,這個(gè)函數(shù)就變成了一個(gè)可以隨意添增屬性的實(shí)例或?qū)ο蟆?/p>

Object.prototype.create = function(obj) {
    function Fun() {}
    Fun.prototype = obj;
    return new Fun();
}

缺點(diǎn)有兩點(diǎn):第一點(diǎn)是無(wú)法傳遞參數(shù),第二點(diǎn)是引用類(lèi)型存在變量的污染。

5:寄生式繼承

寄生式繼承的思路與寄生構(gòu)造函數(shù)和工廠模式類(lèi)似,即創(chuàng)建一個(gè)僅用于封裝繼承過(guò)程的函數(shù)。

目的:在原型式繼承的基礎(chǔ)上,寄生增加了一些新的方法和屬性。

它的特點(diǎn)同原型式繼承一樣,也是無(wú)法傳遞參數(shù),而且引用的數(shù)據(jù)類(lèi)型也容易存在樣式污染。

Object.createNew()

Object.prototype.createNew = function(obj){
    var newObj = Object.create(obj);
    //獲取長(zhǎng)度等于一個(gè)function
    newObj.getLength = function(){ ... };
    return newObj;
}
6:寄生組合繼承

目的:為了解決數(shù)據(jù)重復(fù)拷貝兩遍的問(wèn)題。

Super只執(zhí)行一次。

//定義Super構(gòu)造函數(shù)
function Super(name) {
  this.name = name;
  this.value = ["Hello", "Word"];
}
//在super的原型鏈添加一個(gè)getName
Super.prototype.getName = function() {
  return this.name;
};
//定義Sub
function Sub(name, age) {
  //調(diào)用構(gòu)造函數(shù)繼承
  Super.call(this, name);
  this.age = age;
}

let prototype = Object.create(Super.prototype);
prototype.constructor = Sub;
Sub.prototype = prototype;

Sub.prototype.getAge = function(){
  return this.age;
}

const instance1 = new Sub("Eric", 23);
const instance2 = new Sub("Vico", 23);
instance1.value.push("!");
instance2.value.push("!!");
7:繼承多個(gè)對(duì)象

借助原型式繼承Object.create拿到SuperClass,也就是父類(lèi),拿到父類(lèi)的prototype之后把它賦給ClassOne,再然后我們將ClassTwo的prototype使用一個(gè)Object.assign,一個(gè)對(duì)象的拷貝,把它拷貝到ClassOne里面來(lái),然后最后ClassOne.prototype.constructor等于ClassOne。

也就是使用一個(gè)Class.assign把所有我們想要繼承的父類(lèi)的prototype全部組合到一起完成一個(gè)拷貝,之后再賦給對(duì)象。

function 

ClassOne.prototype = Object.create(SuperClass.prototype);

Object.assign(ClassOne.prototype, ClassTwo.prototype);

ClassOne.prototype.constructor = ClassOne;

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

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

相關(guān)文章

  • JavaScript常用6大繼承方式解析

    摘要:特點(diǎn)跟借用構(gòu)造函數(shù)模式一樣,每次創(chuàng)建對(duì)象都會(huì)創(chuàng)建一遍方法。缺點(diǎn)寄生組合式繼承使用時(shí)說(shuō)明解決了組合繼承存在的問(wèn)題特點(diǎn)只調(diào)用了一次構(gòu)造函數(shù),并且因此避免了在上面創(chuàng)建不必要的多余的屬性原型鏈還能保持不變還能夠正常使用和缺點(diǎn)參考資料 原型鏈繼承 //父類(lèi) function Person(name, age) { this.name = name; this.age = age; ...

    yearsj 評(píng)論0 收藏0
  • JavaScript繼承方式詳解

    摘要:可以通過(guò)構(gòu)造函數(shù)和原型的方式模擬實(shí)現(xiàn)類(lèi)的功能。原型式繼承與類(lèi)式繼承類(lèi)式繼承是在子類(lèi)型構(gòu)造函數(shù)的內(nèi)部調(diào)用超類(lèi)型的構(gòu)造函數(shù)。寄生式繼承這種繼承方式是把原型式工廠模式結(jié)合起來(lái),目的是為了封裝創(chuàng)建的過(guò)程。 js繼承的概念 js里常用的如下兩種繼承方式: 原型鏈繼承(對(duì)象間的繼承) 類(lèi)式繼承(構(gòu)造函數(shù)間的繼承) 由于js不像java那樣是真正面向?qū)ο蟮恼Z(yǔ)言,js是基于對(duì)象的,它沒(méi)有類(lèi)的概念。...

    Yangyang 評(píng)論0 收藏0
  • JavaScript 繼承方式詳解

    摘要:原型繼承與類(lèi)繼承類(lèi)繼承是在子類(lèi)型構(gòu)造函數(shù)的內(nèi)部調(diào)用父類(lèi)型的構(gòu)造函數(shù)原型式繼承是借助已有的對(duì)象創(chuàng)建新的對(duì)象,將子類(lèi)的原型指向父類(lèi)。 JavaScript 繼承方式的概念 js 中實(shí)現(xiàn)繼承有兩種常用方式: 原型鏈繼承(對(duì)象間的繼承) 類(lèi)式繼承(構(gòu)造函數(shù)間的繼承) JavaScript不是真正的面向?qū)ο蟮恼Z(yǔ)言,想實(shí)現(xiàn)繼承可以用JS的原型prototype機(jī)制或者call和apply方法 在面...

    YuboonaZhang 評(píng)論0 收藏0
  • JavaScript常用八種繼承方案

    摘要:原型式繼承利用一個(gè)空對(duì)象作為中介,將某個(gè)對(duì)象直接賦值給空對(duì)象構(gòu)造函數(shù)的原型。其中表示構(gòu)造函數(shù),一個(gè)類(lèi)中只能有一個(gè)構(gòu)造函數(shù),有多個(gè)會(huì)報(bào)出錯(cuò)誤如果沒(méi)有顯式指定構(gòu)造方法,則會(huì)添加默認(rèn)的方法,使用例子如下。 (關(guān)注福利,關(guān)注本公眾號(hào)回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo))showImg(https://segmentfault.com/img/rem...

    wpw 評(píng)論0 收藏0
  • JavaScript - 原型&原型鏈

    摘要:可以看出,這個(gè)查找過(guò)程是一個(gè)鏈?zhǔn)降牟檎?,每個(gè)對(duì)象都有一個(gè)到它自身原型對(duì)象的鏈接,這些鏈接組件的整個(gè)鏈條就是原型鏈。原型的構(gòu)建字面量方式當(dāng)通過(guò)字面量方式創(chuàng)建對(duì)象時(shí),它的原型就是。 面向?qū)ο?JavaScript沒(méi)有類(lèi)(class)的概念的(ES6 中的class也只不過(guò)是語(yǔ)法糖,并非真正意義上的類(lèi)),而在JavaScript中,在 JavaScript 中,除了 String, Numb...

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

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

0條評(píng)論

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