欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript中常見的繼承方式總結(jié)

 更新時(shí)間:2022年11月15日 11:56:45   作者:beckyyyy  
這篇文章主要和大家詳細(xì)介紹了JavaScript中常見的幾種繼承方式,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)JavaScript有一定幫助,需要的小伙伴可以參考下面文章詳細(xì)內(nèi)容

JS和Java中雖然都有對(duì)象的概念,但這兩種對(duì)象卻大有不同。Java的對(duì)象是基于類創(chuàng)建的,JS的對(duì)象卻是基于一個(gè)特殊的對(duì)象——原型對(duì)象——創(chuàng)建的,之前看到一個(gè)蓋房子的比喻,在Java中蓋房子是先畫好圖紙?jiān)偕w房子,JS中蓋房子卻是先蓋一個(gè)樣板房再蓋其他房子,覺得也挺貼切。

所以JS中的繼承和Java中的繼承就大有不同了,是基于原型對(duì)象的,如果兩個(gè)對(duì)象形成繼承關(guān)系,那必然是其中一個(gè)對(duì)象的原型鏈上存在一個(gè)指針指向另一個(gè)對(duì)象。即使JS中的兩個(gè)類聲明了繼承關(guān)系,也是表現(xiàn)在原型對(duì)象上。比如:

class A {
    say() {
        console.log('say: hello!');
    }
}

class B extends A {
    constructor() {
        super();
    }
}

console.log(A.prototype); // {constructor: ?, say: ?}
console.log(B.__proto__); // class A {}
console.log(B.prototype); // A?{constructor: ?}

首先,類是JS中函數(shù)的語法糖,并且在JS中函數(shù)本身也是對(duì)象,也就是說A和B是兩個(gè)對(duì)象,所以extends操作使得B自身的原型屬性__proto__指向了A,相當(dāng)于const B = Object.create(A);。

其次,類的繼承關(guān)系也影響其生成的實(shí)例,眾所周知,函數(shù)本身存在一個(gè)特殊的對(duì)象屬性:prototype,函數(shù)經(jīng)過構(gòu)造調(diào)用產(chǎn)生的實(shí)例的原型屬性__proto__是指向這個(gè)對(duì)象的,而extends操作修改了B的prototype對(duì)象,所以B實(shí)例上的原型屬性__proto__也就被修改了,通過B實(shí)例的原型屬性__proto__能找到A的prototype,即在B實(shí)例的原型鏈上能找到A的prototype。

const b = new B();
console.log(b.__proto__); // A?{constructor: ?} 即B.prototype
console.log(b.__proto__.__proto__); // {constructor: ?, say: ?} 即A.prototype

在JS中使用字面量定義的對(duì)象時(shí),其默認(rèn)的原型屬性__proto__指向Object的prototype對(duì)象,相當(dāng)于默認(rèn)繼承自O(shè)bject,所以字面量對(duì)象可以調(diào)用Object的實(shí)例方法。

可以使用isPrototypeOf來判斷一個(gè)對(duì)象是否在另一個(gè)對(duì)象的原型鏈上。

由上述可知,JS中的繼承關(guān)系與原型對(duì)象密切相關(guān),為了達(dá)到繼承的關(guān)聯(lián)關(guān)系(共享某些屬性和方法),就要從原型對(duì)象著手:

1.使用Object.create的方式創(chuàng)建對(duì)象,使兩個(gè)對(duì)象直接產(chǎn)生繼承關(guān)系

const o1 = {
    name: 'o1',
    age: 18,
    walk() {
        console.log('walking...')
    }
};
const o2 = Object.create(o1);
console.log(o2.__proto__); // {name: 'o1', age: 18}
console.log(o2.walk()); // walking...
console.log(o1.isPrototypeOf(o2)); // true

2.使用new操作創(chuàng)建對(duì)象,使產(chǎn)生的實(shí)例和類(或函數(shù))的原型對(duì)象產(chǎn)生繼承關(guān)系

const b = new B();
console.log(B.prototype); // A?{constructor: ?}
console.log(b.__proto__); // A?{constructor: ?} 即B.prototype
console.log(B.prototype.isPrototypeOf(b)); // true

3.使用extends關(guān)鍵字使類形成繼承關(guān)系,擴(kuò)展類實(shí)例的原型鏈

class A {
    say() {
        console.log('say: hello!');
    }
}

class B extends A {
    constructor() {
        super();
    }
}

console.log(A.prototype); // {constructor: ?, say: ?}
const b = new B();
console.log(b.__proto__.__proto__); // {constructor: ?, say: ?} 即A.prototype
console.log(A.isPrototypeOf(B)); // true
console.log(A.isPrototypeOf(b)); // false
console.log(A.prototype.isPrototypeOf(b)); // true

4.修改函數(shù)的prototype屬性使函數(shù)形成繼承關(guān)系,擴(kuò)展函數(shù)實(shí)例的原型鏈

function C() {
    this.name = 'c';
    this.operation = function() { return 'printing...'};
}
function D() {}
D.prototype = new C();
const d = new D();
console.log(d.__proto__.__proto__ === C.prototype); // true
console.log(C.prototype.isPrototypeOf(d)); // true
console.log(D.prototype.isPrototypeOf(d)); // true

這里存在一個(gè)問題,就是子類實(shí)例化時(shí)無法向父類的構(gòu)造函數(shù)傳參

5.盜用父類構(gòu)造函數(shù)

在函數(shù)內(nèi)部通過call或apply調(diào)用父類函數(shù)(非構(gòu)造調(diào)用),可繼承父類實(shí)例自身(非原型對(duì)象)的屬性和方法(相當(dāng)于把子類實(shí)例(即this)傳遞進(jìn)父類函數(shù),對(duì)這個(gè)this做了一遍操作),雖然可在初始化時(shí)傳遞參數(shù)給父類,但無法形成原型鏈

function E() {
    C.call(this);
    this.do = function () { return 'do homework'; }
}
const e = new E();
console.log(E.prototype.isPrototypeOf(e)); // true
console.log(C.prototype.isPrototypeOf(e)); // false
console.log(e); // E?{name: 'c', operation: ?, do: ?}
console.log(e.do()); // do homework

子類產(chǎn)生的實(shí)例無法對(duì)父類及其原型對(duì)象應(yīng)用instanceof和isPrototypeOf方法。

此時(shí)如果父類想共享方法給子類,必須把方法直接在定義在函數(shù)內(nèi)部,綁定到實(shí)例上,而無法通過父類的prototype對(duì)象共享。

6.結(jié)合4和5,使得子類實(shí)例可繼承父類原型對(duì)象的屬性和方法,且能形成原型鏈

function E() {
    C.call(this);
    this.do = function () { return 'do homework'; }
}
E.prototype = new C();
const e = new E();
console.log(E.prototype.isPrototypeOf(e)); // true
console.log(C.prototype.isPrototypeOf(e)); // true
console.log(e); // E?{name: 'c', operation: ?, do: ?}
console.log(e.do()); // do homework

7.用Object.create()替換new父類實(shí)例來重寫子類的原型對(duì)象

function inheritatePrototype(subT, superT) {
  let proto = Object.create(superT.prototype);
  proto.constructor = subT;
  subT.prototype = proto;
}

inheritatePrototype(E, C);

可以舍去new中不需要的操作

8.通過工廠方式共享屬性和方式

類似工廠函數(shù),但不是用裸的Object,以某種方式取得對(duì)象(如new等返回新對(duì)象的函數(shù)),對(duì)此對(duì)象加屬性或方法以增強(qiáng)功能,并返回對(duì)象。

function createAnother(original) {
  let clone = Object.create(original);
  clone.xx = xxx;
  return clone;
}

適合主要關(guān)注對(duì)象,而不在乎類型和構(gòu)造函數(shù)的場景

存在的問題: 必須在構(gòu)造函數(shù)中定義方法(屬于實(shí)例非原型對(duì)象的方法),函數(shù)不能重用

到此這篇關(guān)于JavaScript中常見的繼承方式總結(jié)的文章就介紹到這了,更多相關(guān)JavaScript繼承方式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JavaScript canvas繪制圓形加載進(jìn)度條

    JavaScript canvas繪制圓形加載進(jìn)度條

    這篇文章主要為大家詳細(xì)介紹了JavaScript canvas繪制圓形加載進(jìn)度條,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • 微信小程序返回上一頁傳參并刷新過程解析

    微信小程序返回上一頁傳參并刷新過程解析

    這篇文章主要介紹了微信小程序返回上一頁傳參并刷新過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • javascript 文章截取部分無損html顯示實(shí)現(xiàn)代碼

    javascript 文章截取部分無損html顯示實(shí)現(xiàn)代碼

    近在做一些內(nèi)容搜索的工作,搜索出來的內(nèi)容為html格式,列表部分需要顯示每項(xiàng)內(nèi)容的一部分。
    2010-05-05
  • JS實(shí)現(xiàn)百度搜索框

    JS實(shí)現(xiàn)百度搜索框

    這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)百度搜索框,實(shí)時(shí)返回搜索建議項(xiàng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-02-02
  • JS煙花背景效果實(shí)現(xiàn)方法

    JS煙花背景效果實(shí)現(xiàn)方法

    這篇文章主要介紹了JS煙花背景效果實(shí)現(xiàn)方法,實(shí)例分析了javascript操作dom元素實(shí)現(xiàn)煙花特效的技巧,需要的朋友可以參考下
    2015-03-03
  • jquery 實(shí)現(xiàn)輸入郵箱時(shí)自動(dòng)補(bǔ)全下拉提示功能

    jquery 實(shí)現(xiàn)輸入郵箱時(shí)自動(dòng)補(bǔ)全下拉提示功能

    大家在做Web項(xiàng)目,都會(huì)有注冊(cè)登錄模塊,如果是郵箱注冊(cè),想要在輸入@后觸發(fā)下拉框顯示各個(gè)郵箱的功能。下面介紹一款jQuery實(shí)現(xiàn)輸入郵箱的時(shí)候,可自動(dòng)補(bǔ)全郵箱地址,也可稱為是“輸入提示”的功能,比如輸入aaa時(shí),自動(dòng)變成aaa@163.com,有效提升網(wǎng)頁的人性化體驗(yàn)
    2015-10-10
  • Bootstrap網(wǎng)格系統(tǒng)詳解

    Bootstrap網(wǎng)格系統(tǒng)詳解

    bootstrap框架中的網(wǎng)格系統(tǒng)就是將容器平分成12份,在使用的時(shí)候可以根據(jù)實(shí)際情況重新編譯LESS/SASS源碼來修改12這個(gè)數(shù)值。接下來通過本文給大家介紹Bootstrap網(wǎng)格系統(tǒng),感興趣的朋友一起學(xué)習(xí)
    2016-04-04
  • Js數(shù)組的操作push,pop,shift,unshift等方法詳細(xì)介紹

    Js數(shù)組的操作push,pop,shift,unshift等方法詳細(xì)介紹

    js中針對(duì)數(shù)組操作的方法還是比較多的,今天突然想到來總結(jié)一下,也算是溫故而知新吧。不過不會(huì)針對(duì)每個(gè)方法進(jìn)行講解,我只是選擇其中的一些來講,感興趣的朋友可以研究一下
    2012-12-12
  • JS實(shí)現(xiàn)的論壇Ajax打分效果完整實(shí)例

    JS實(shí)現(xiàn)的論壇Ajax打分效果完整實(shí)例

    這篇文章主要介紹了JS實(shí)現(xiàn)的論壇Ajax打分效果,以完整實(shí)例形式分析了JavaScript響應(yīng)鼠標(biāo)事件動(dòng)態(tài)操作頁面元素樣式的相關(guān)技巧,需要的朋友可以參考下
    2015-10-10
  • 深入理解Javascript中的循環(huán)優(yōu)化

    深入理解Javascript中的循環(huán)優(yōu)化

    這篇文章介紹了Javascript中的循環(huán)優(yōu)化,有需要的朋友可以參考一下
    2013-11-11

最新評(píng)論