亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

javascript 原型與原型鏈的理解及應(yīng)用實例分析

 更新時間:2020年02月10日 12:07:39   作者:懷素真  
這篇文章主要介紹了javascript 原型與原型鏈的理解及應(yīng)用,結(jié)合實例形式分析了javascript原型與原型鏈的具體原理、功能、使用方法及操作注意事項,需要的朋友可以參考下

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

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

比如對象A與對象B之間,它們兩個是相對獨立的個體,互不干擾,對象A修改自身的屬性不會影響到對象B。

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

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

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

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

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

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

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

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

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

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

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

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

function Base(name) {
  this.name = name;
}
//我們在原型對象上添加公共屬性
Base.prototype.status = '開始';
//我們在原型對象上添加公共方法
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);
//修改原型上的屬性,則實例對象也會跟著改變
Base.prototype.status = '停止';
console.log(A.status);
console.log(B.status);

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

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

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

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

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

這時,Base.prototype.constructor 指向了 Child,這顯然是有問題。

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

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

那怎么通過原型與原型鏈,讓你一對象繼承于另一個對象呢?

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

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

這樣有一個問題,當(dāng)修改 B.__proto__.name = 'B'; 時,對象A也會受到影響。

我們可以通過ES5提供的 Object.create() 來解決此問題,Object.create()可以通過指定的 原型對象 創(chuàng)建一個新對象。

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

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

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

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

相關(guān)文章

  • JavaScript中的10個常見錯誤及解決方法

    JavaScript中的10個常見錯誤及解決方法

    JavaScript 作為最流行的編程語言之一,為絕大多數(shù)網(wǎng)站和應(yīng)用提供動力,然而,其靈活性和動態(tài)特性有時會導(dǎo)致常見錯誤,本文將探討 JavaScript 中的 10 個常見錯誤,并提供相應(yīng)的解決方案,需要的朋友可以參考下
    2024-09-09
  • es7學(xué)習(xí)教程之Decorators(修飾器)詳解

    es7學(xué)習(xí)教程之Decorators(修飾器)詳解

    這篇文章主要給大家介紹了關(guān)于es7中Decorators(修飾器)的相關(guān)資料,文中通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面跟著小編一起來學(xué)習(xí)學(xué)習(xí)吧。
    2017-07-07
  • Javascript Dom元素獲取和添加詳解

    Javascript Dom元素獲取和添加詳解

    這篇文章主要介紹了Javascript Dom元素獲取和添加詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-09-09
  • 將字符串轉(zhuǎn)換成gb2312或者utf-8編碼的參數(shù)(js版)

    將字符串轉(zhuǎn)換成gb2312或者utf-8編碼的參數(shù)(js版)

    直接在url中傳遞中文參數(shù)時,讀到的中文都是亂碼,那么我們應(yīng)該怎么將這些參數(shù)轉(zhuǎn)換呢,接下來與大家分享下將字符串轉(zhuǎn)換成utf-8或者gb2312編碼的參數(shù)的技巧
    2013-04-04
  • js實現(xiàn)卡片式項目管理界面UI設(shè)計效果

    js實現(xiàn)卡片式項目管理界面UI設(shè)計效果

    這篇文章主要介紹了js實現(xiàn)卡片式項目管理界面UI設(shè)計效果,該UI設(shè)計中,將各個項目以卡片的方式堆疊排列在屏幕上,當(dāng)點擊了其中的某個項目的時候,該項目圖片會全屏放大,向下滾動鼠標(biāo)可以看到該項目的介紹信息,需要的朋友可以參考下
    2015-12-12
  • JavaScript中淺講ajax圖文詳解

    JavaScript中淺講ajax圖文詳解

    ajax對于各位來說,應(yīng)該都不陌生,正因為ajax的產(chǎn)生,導(dǎo)致前臺頁面和服務(wù)器之間的數(shù)據(jù)傳輸變得非常容易,同時還可以實現(xiàn)頁面的局部刷新。本文圖文并茂給大家介紹了js中ajax知識,需要的朋友一起學(xué)習(xí)吧
    2016-11-11
  • 關(guān)閉瀏覽器時提示onbeforeunload事件

    關(guān)閉瀏覽器時提示onbeforeunload事件

    這篇文章主要介紹了關(guān)閉瀏覽器時提示onbeforeunload事件,有需要的朋友可以參考一下
    2013-12-12
  • 用js一次改變多個input的readonly屬性值的方法

    用js一次改變多個input的readonly屬性值的方法

    這篇文章主要介紹了用js一次改變多個input的readonly屬性值的方法,需要的朋友可以參考下
    2014-06-06
  • 利用用JS實現(xiàn)一個實時小鬧鐘

    利用用JS實現(xiàn)一個實時小鬧鐘

    天我們來聊聊如何使用JS來創(chuàng)建一個實時的小鬧鐘,這個小鬧鐘十分的有趣,小伙伴們可以運行一下,看看跟你電腦上的時間是否對的上呢,文章通過代碼示例介紹的非常詳細(xì),需要的朋友可以參考下
    2023-11-11
  • 淺析IE10兼容性問題(frameset的cols屬性)

    淺析IE10兼容性問題(frameset的cols屬性)

    主頁用frameset嵌了兩個頁面,左側(cè)為菜單欄,可以通過改變 frameset的cols來收縮。別的瀏覽器正常,但I(xiàn)E10卻沒任何的反應(yīng)
    2014-01-01

最新評論