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

javascript 原型與原型鏈的理解及實(shí)例分析

 更新時(shí)間:2019年11月23日 10:50:49   作者:懷素真  
這篇文章主要介紹了javascript 原型與原型鏈的理解,結(jié)合實(shí)例形式分析了javascript 原型與原型鏈的原理、使用方法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下

本文實(shí)例講述了javascript 原型與原型鏈的理解。分享給大家供大家參考,具體如下:

javascript中一切皆對(duì)象,但是由于沒(méi)有Class類的概念,所以就無(wú)法很好的表達(dá)對(duì)象與對(duì)象之間的關(guān)系了。

比如對(duì)象A與對(duì)象B之間,它們兩個(gè)是相對(duì)獨(dú)立的個(gè)體,互不干擾,對(duì)象A修改自身的屬性不會(huì)影響到對(duì)象B。

雖然這很好,但是有一個(gè)問(wèn)題,如果對(duì)象A與對(duì)象B都有一個(gè)方法 run() ,并且代碼也一樣,那對(duì)象A與對(duì)象B各自都獨(dú)立擁有一份 run() 方法的完整代碼,這是需要資源去保存的。

一旦我們程序中應(yīng)用的對(duì)象過(guò)多,那這種資源消耗會(huì)是巨大的。那有沒(méi)有一種方法可以讓對(duì)象A與對(duì)象B擁有一些公共的屬性和方法,讓它們之前有某種聯(lián)系?

我們?cè)O(shè)想一下,會(huì)不會(huì)存在一個(gè) common對(duì)象(公共對(duì)象),common對(duì)象上保存著公共的屬性和方法,而對(duì)象A與對(duì)象B里面有一個(gè)prototype屬性指向這個(gè) common對(duì)象,

當(dāng)然我們調(diào)用對(duì)象A或?qū)ο驜的屬性和方法時(shí),如果在自身對(duì)象中沒(méi)有找到,就去prototype這個(gè)屬性指向的對(duì)象上面去找。

而common對(duì)象本身也有一個(gè)prototype屬性指向更上一級(jí)的common對(duì)象,然后一直往上找啊找,直到為null,就停止。

這種不斷的從下往上找的這種路徑,就像鏈條一樣,我們稱它為 原型鏈,而那個(gè)common對(duì)象,我們稱它為 原型對(duì)象。

我們來(lái)看一個(gè)構(gòu)造函數(shù)

function Base(name) {
  this.name = name;
}
let A = new Base('A');
let B = new Base('B');
//每一個(gè)函數(shù)都有一個(gè)prototype屬性,指向該函數(shù)的原型對(duì)象
console.log(Base.prototype);
//當(dāng)然原型對(duì)象也是一個(gè)對(duì)象,它也有一個(gè)constructor,指向構(gòu)造函數(shù)
console.log(Base.prototype.constructor === Base);
//每一個(gè)實(shí)例對(duì)象的constructor都指向創(chuàng)建它們的構(gòu)造函數(shù)
console.log(A.constructor === Base);
console.log(B.constructor === Base);
//每一個(gè)實(shí)例對(duì)象都有一個(gè)__proto__屬性,該屬性指向構(gòu)造函數(shù)的原型對(duì)象
console.log(A.__proto__ === Base.prototype);
console.log(B.__proto__ === Base.prototype);

1、每一個(gè)函數(shù)都有一個(gè)prototype屬性,它指向該函數(shù)的原型對(duì)象。

2、原型對(duì)象也是對(duì)象,它也有自已的constructor,它指向構(gòu)造函數(shù)Base()。換句話說(shuō),其實(shí)原型對(duì)象也是構(gòu)造函數(shù)Base()的一個(gè)實(shí)例。只不過(guò)比較特殊,用來(lái)存放公共屬性和方法的。

3、每一個(gè)通過(guò)構(gòu)造函數(shù)Base()創(chuàng)建的實(shí)例對(duì)象,都有一個(gè)constructor,指向創(chuàng)建它們的構(gòu)造函數(shù)。

4、每一個(gè)對(duì)象,都有一個(gè) __proto__ 屬性,指向構(gòu)造函數(shù)Base()的 原型對(duì)象。換句話說(shuō),__proto__ 是將 原型 串聯(lián)起來(lái)形成鏈條的關(guān)鍵。不然對(duì)象A與對(duì)象B都無(wú)法找到原型對(duì)象上的公共屬性和方法。

function Base(name) {
  this.name = name;
}
//我們?cè)谠蛯?duì)象上添加公共屬性
Base.prototype.status = '開(kāi)始';
//我們?cè)谠蛯?duì)象上添加公共方法
Base.prototype.run = function() {
  console.log(this.name + ' run ...');
};
let A = new Base('A');
let B = new Base('B');
A.run();
B.run();
console.log(A.status);
console.log(B.status);
//修改原型上的屬性,則實(shí)例對(duì)象也會(huì)跟著改變
Base.prototype.status = '停止';
console.log(A.status);
console.log(B.status);

通過(guò)原型與原型鏈,讓對(duì)象與對(duì)象之間有了關(guān)聯(lián)關(guān)系。

那如何通過(guò)原型與原型鏈,讓一個(gè)構(gòu)造函數(shù)繼承于另一個(gè)構(gòu)造函數(shù)?

比如,我們要讓構(gòu)造函數(shù)Child 繼承于 構(gòu)造函數(shù)Base,只需要讓 Child 的 prototype 指向 Base的 原型對(duì)象,不就可以了?

function Base(name) {
}
Base.prototype.name = 'Base';
Base.prototype.run = function () {
  console.log(this.name + ' run ...');
};
function Child() {
}
Child.prototype = Base.prototype;
//注意這個(gè)時(shí)候,Child.prototype對(duì)象的constructor屬性指向了Base
//這就導(dǎo)致通過(guò)構(gòu)造函數(shù)Child創(chuàng)建的實(shí)例對(duì)象,對(duì)象的constructor屬性會(huì)指向Base,而不是Child,這會(huì)導(dǎo)致混亂。
//所以我們重新設(shè)置Child.prototype.constructor指向Child
Child.prototype.constructor = Child;
let c = new Child();
console.log(c.name);
c.run();

這樣有一個(gè)問(wèn)題,Child.prototype 與 Base.prototype 指向同一個(gè)原型對(duì)象,任何對(duì) Child.prototype 的修改都會(huì)反應(yīng)到 Base.prototype 上面。

這時(shí),Base.prototype.constructor 指向了 Child,這顯然是有問(wèn)題。

我們只能通過(guò)一個(gè)中間的空構(gòu)造函數(shù),來(lái)完成原型的指向。

function Base(name) {
}
Base.prototype.name = 'Base';
Base.prototype.run = function () {
  console.log(this.name + ' run ...');
};
function Child() {
}
//創(chuàng)建一個(gè)中間的空構(gòu)造函數(shù)
function Mid() {
}
//讓該空構(gòu)造函數(shù)的prototype指向Base的原型對(duì)象
Mid.prototype = Base.prototype;
//再讓Child的prototype指向該空構(gòu)造函數(shù)的一個(gè)實(shí)例
Child.prototype = new Mid();
//這樣,當(dāng)修改Child.prototype.constructor時(shí),Base.prototype就不會(huì)受影響了
Child.prototype.constructor = Child;
let c = new Child();
console.log(c.name);
c.run();
//Base.prototype的constructor仍然指向Base,沒(méi)有受到影響
console.log(Base.prototype.constructor);

那怎么通過(guò)原型與原型鏈,讓你一對(duì)象繼承于另一個(gè)對(duì)象呢?

比如,我們要讓對(duì)象B繼承于對(duì)象A,無(wú)非就是想要拿到對(duì)象A的屬性和方法,這么一想,那通過(guò)把對(duì)象B的 __proto__  指向 對(duì)象A,不就可以實(shí)現(xiàn)了?

let A = {
  name: 'A',
  run() {
    console.log(this.name + ' run ...');
  }
};
console.log(A.name);
A.run();
let B = {};
//讓對(duì)象B的__proto__指向?qū)ο驛
B.__proto__ = A;
//當(dāng)對(duì)象B調(diào)用run()方法時(shí)會(huì)在自身上找,如果沒(méi)找到,則通過(guò)__proto__向上找
//由于__proto__指向?qū)ο驛,所以最終會(huì)在對(duì)象A中找到run()方法
B.run();
B.__proto__.name = 'B';
console.log(A.name);
console.log(B.name);

這樣有一個(gè)問(wèn)題,當(dāng)修改 B.__proto__.name = 'B'; 時(shí),對(duì)象A也會(huì)受到影響。

我們可以通過(guò)ES5提供的 Object.create() 來(lái)解決此問(wèn)題,Object.create()可以通過(guò)指定的 原型對(duì)象 創(chuàng)建一個(gè)新對(duì)象。

let A = {
  name: 'A',
  run() {
    console.log(this.name + ' run ...');
  }
};
console.log(A.name);
A.run();
let B = {};
//通過(guò)Object.create()創(chuàng)建一個(gè)以對(duì)象A為原型對(duì)象的新對(duì)象
//讓對(duì)象B的__proto__指向該新對(duì)象
//這樣再操作B.__proto__中的屬性就與對(duì)象A無(wú)關(guān)了。
B.__proto__ = Object.create(A);
B.run();
B.__proto__.name = 'B';
console.log(A.name);
console.log(B.name);

感興趣的朋友可以使用在線HTML/CSS/JavaScript代碼運(yùn)行工具http://tools.jb51.net/code/HtmlJsRun測(cè)試上述代碼運(yùn)行效果。

更多關(guān)于JavaScript相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《javascript面向?qū)ο笕腴T教程》、《JavaScript錯(cuò)誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript數(shù)學(xué)運(yùn)算用法總結(jié)

希望本文所述對(duì)大家JavaScript程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • 微信小程序出現(xiàn)wx.navigateTo頁(yè)面不跳轉(zhuǎn)問(wèn)題的解決方法

    微信小程序出現(xiàn)wx.navigateTo頁(yè)面不跳轉(zhuǎn)問(wèn)題的解決方法

    這篇文章主要介紹了微信小程序出現(xiàn)wx.navigateTo頁(yè)面不跳轉(zhuǎn)問(wèn)題的解決方法,簡(jiǎn)單分析了微信小程序出現(xiàn)wx.navigateTo頁(yè)面不跳轉(zhuǎn)情況的原因及相應(yīng)的解決方法,需要的朋友可以參考下
    2017-12-12
  • JavaScript利用正則表達(dá)式去除日期中的“-”

    JavaScript利用正則表達(dá)式去除日期中的“-”

    第一種,將日期字符串先截取,然后拼接;第二種,就是利用正則表達(dá)式去掉“-”本例選擇第二種,比較快捷不容易出錯(cuò)
    2014-07-07
  • 一文詳解Web Audio瀏覽器采集麥克風(fēng)音頻數(shù)據(jù)

    一文詳解Web Audio瀏覽器采集麥克風(fēng)音頻數(shù)據(jù)

    這篇文章主要為大家介紹Web Audio瀏覽器采集麥克風(fēng)音頻數(shù)據(jù)實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • 詳解JS中的立即執(zhí)行函數(shù)

    詳解JS中的立即執(zhí)行函數(shù)

    本文主要介紹了js中立即執(zhí)行函數(shù)的相關(guān)知識(shí),具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2017-02-02
  • 微信小程序-圖片、錄音、音頻播放、音樂(lè)播放、視頻、文件代碼實(shí)例

    微信小程序-圖片、錄音、音頻播放、音樂(lè)播放、視頻、文件代碼實(shí)例

    本篇文章主要介紹了微信小程序-圖片、錄音、音頻播放、音樂(lè)播放、視屏、文件代碼實(shí)例,有興趣的可以了解一下。
    2016-11-11
  • 微信小程序自定義Dialog彈框

    微信小程序自定義Dialog彈框

    這篇文章主要為大家詳細(xì)介紹了微信小程序自定義Dialog彈框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • 使用JS實(shí)現(xiàn)任意位置縮放圖片功能

    使用JS實(shí)現(xiàn)任意位置縮放圖片功能

    本文將用一個(gè)簡(jiǎn)單的例子詳細(xì)講解如何用原生JS一步步實(shí)現(xiàn)完整的任意位置縮放圖片功能,無(wú)任何第三方依賴,指針事件 進(jìn)行多端統(tǒng)一的事件監(jiān)聽(tīng),干貨滿滿,需要的朋友可以參考下
    2024-04-04
  • JavaScript制作年歷的示例代碼

    JavaScript制作年歷的示例代碼

    本文主要介紹了JavaScript制作年歷的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2012-05-05
  • 微信小程序傳值以及獲取值方法的詳解

    微信小程序傳值以及獲取值方法的詳解

    這篇文章主要介紹了微信小程序傳值以及獲取值方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • JavaScript注入漏洞的原理及防范(詳解)

    JavaScript注入漏洞的原理及防范(詳解)

    下面小編就為大家?guī)?lái)一篇JavaScript注入漏洞的原理及防范(詳解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-12-12

最新評(píng)論