溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

JavaScript原型和原型鏈?zhǔn)鞘裁匆馑?/h1>
發(fā)布時(shí)間:2021-09-27 10:49:34 來(lái)源:億速云 閱讀:144 作者:小新 欄目:開(kāi)發(fā)技術(shù)

小編給大家分享一下JavaScript原型和原型鏈?zhǔn)鞘裁匆馑迹嘈糯蟛糠秩硕歼€不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

一、原型、原型鏈相等關(guān)系理解

首先我們要清楚明白兩個(gè)概念:

js分為函數(shù)對(duì)象和普通對(duì)象,每個(gè)對(duì)象都有__proto__屬性,但是只有函數(shù)對(duì)象才有prototype屬性
ObjectFunction都是js內(nèi)置的函數(shù), 類似的還有我們常用到的Array、RegExp、DateBoolean、Number、String

這兩個(gè)概念大家跟我一起讀三遍并記住,后面會(huì)用到

那么__proto__prototype到底是什么,兩個(gè)概念理解它們

  • 屬性__proto__是一個(gè)對(duì)象,它有兩個(gè)屬性,constructor__proto__ ;

  • 原型對(duì)象prototype有一個(gè)默認(rèn)的constructor屬性,用于記錄實(shí)例是由哪個(gè)構(gòu)造函數(shù)創(chuàng)建;

這兩個(gè)概念大家跟我一起讀三遍并記住,后面會(huì)用到

有以下構(gòu)造函數(shù)Person,他的原型上有所屬國(guó)屬性motherland='China'

 function Person(name, age){ 
    this.name = name;
    this.age = age;
 }
 
 Person.prototype.motherland = 'China'

通過(guò)new Person()創(chuàng)建的person01實(shí)例

 let person01 = new Person('小明', 18);

js之父在設(shè)計(jì)js原型、原型鏈的時(shí)候遵從以下兩個(gè)準(zhǔn)則

 Person.prototype.constructor == Person // **準(zhǔn)則1:原型對(duì)象(即Person.prototype)的constructor指向構(gòu)造函數(shù)本身**
 person01.__proto__ == Person.prototype // **準(zhǔn)則2:實(shí)例(即person01)的__proto__和原型對(duì)象指向同一個(gè)地方**

這兩個(gè)準(zhǔn)則大家跟我一起讀三遍并記住,后面會(huì)用到

記住以上四個(gè)概念兩個(gè)準(zhǔn)則,任何原型鏈相等判斷都能判斷正確;

大家可以對(duì)照上圖,看看自己概念準(zhǔn)則是否弄清楚了,一定要對(duì)照上圖哦

// 從上方 function Foo() 開(kāi)始分析這一張經(jīng)典之圖
function Foo()
let f1 = new Foo();
let f2 = new Foo();

f1.__proto__ = Foo.prototype; // 準(zhǔn)則2
f2.__proto__ = Foo.prototype; // 準(zhǔn)則2
Foo.prototype.__proto__ = Object.prototype; // 準(zhǔn)則2 (Foo.prototype本質(zhì)也是普通對(duì)象,可適用準(zhǔn)則2)
Object.prototype.__proto__ = null; // 原型鏈到此停止
Foo.prototype.constructor = Foo; // 準(zhǔn)則1
Foo.__proto__ = Function.prototype; // 準(zhǔn)則2
Function.prototype.__proto__  = Object.prototype; //  準(zhǔn)則2 (Function.prototype本質(zhì)也是普通對(duì)象,可適用準(zhǔn)則2)
Object.prototype.__proto__ = null; // 原型鏈到此停止
// **此處注意Foo 和 Function的區(qū)別, Foo是 Function的實(shí)例**

// 從中間 Function Object()開(kāi)始分析這一張經(jīng)典之圖
Function Object()
let o1 = new  Object();
let o2 = new  Object();

o1.__proto__ = Object.prototype; // 準(zhǔn)則2
o2.__proto__ = Object.prototype; // 準(zhǔn)則2
Object.prototype.__proto__ = null; // 原型鏈到此停止
Object.prototype.constructor = Object; // 準(zhǔn)則1
Object.__proto__ = Function.prototype // 準(zhǔn)則2 (Object本質(zhì)也是函數(shù));
// 此處有點(diǎn)繞,Object本質(zhì)是函數(shù),F(xiàn)unction本質(zhì)是對(duì)象
Function.prototype.__proto__ =  Object.prototype; // 準(zhǔn)則2 (Function.prototype本質(zhì)也是普通對(duì)象,可適用準(zhǔn)則2)
Object.prototype.__proto__ = null; // 原型鏈到此停止

// 從下方 Function Function()開(kāi)始分析這一張經(jīng)典之圖
Function Function()
Function.__proto__ = Function.prototype // 準(zhǔn)則2
Function.prototype.constructor = Function; // 準(zhǔn)則1

由此可以得出結(jié)論: 除了Object的原型對(duì)象(Object.prototype)的__proto__指向null,其他內(nèi)置函數(shù)對(duì)象的原型對(duì)象(例如:Array.prototype)和自定義構(gòu)造函數(shù)的 __proto__都指向Object.prototype, 因?yàn)樵蛯?duì)象本身是普通對(duì)象。 即:

Object.prototype.__proto__ = null;
Array.prototype.__proto__ = Object.prototype;
Foo.prototype.__proto__  = Object.prototype;

二:原型、原型鏈的意思何在

理解了這些相等關(guān)系之后,我們思考,原型、原型鏈的意思何在?原型對(duì)象的作用,是用來(lái)存放實(shí)例中共有的那部份屬性、方法,可以大大減少內(nèi)存消耗。

用我們文章開(kāi)始的Person構(gòu)造函數(shù)和person01實(shí)例舉例說(shuō):

console.log(person01)

打印person01, 他有自己屬性 name = '小明',age = 18; 同時(shí)通過(guò)原型鏈關(guān)系,他有屬性motherland = 'China';

我們?cè)賱?chuàng)建person2實(shí)例

let person02 = new Person('小花', 20);
console.log(person02)

打印person02, 他有自己屬性 name = '小花',age = 20; 同時(shí)通過(guò)原型鏈關(guān)系,他有屬性motherland = 'China'; 看出來(lái)了沒(méi)有,原型對(duì)象存放了person01、person02共有的屬性所屬國(guó)motherland = 'China'. 我們不用在每個(gè)實(shí)例上添加motherland 屬性,而是將這一屬性存在他們的構(gòu)造函數(shù)原型對(duì)象上,對(duì)于人類Person這樣的構(gòu)造函數(shù)。相同的屬性、方法還有很多很多,比如我們是黑頭發(fā),我們都有吃,睡這樣一個(gè)方法,當(dāng)相同的屬性、方法越多,原型、原型鏈的意義越大。 那我們可以這樣操作

Person.prototype.hairColor = 'black';
Person.prototype.eat = function(){
    console.log('We usually eat three meals a day.')
}
console.log(person01)
console.log(person02)

此時(shí)我們?cè)俅蛴?code>person01、person02,我們驚喜的發(fā)現(xiàn),他們有了屬性hairColoreat方法;實(shí)例們動(dòng)態(tài)的獲得了Person構(gòu)造函數(shù)之后添加的屬性、方法,這是就是原型、原型鏈的意義所在!可以動(dòng)態(tài)獲取,可以節(jié)省內(nèi)存。

另外我們還要注意:如果person01將頭發(fā)染成了黃色,那么hairColor會(huì)是什么呢?

person01,hairColor = 'yellow';
console.log(person01)
console.log(person02)

可以看到,person01hairColor = 'yellow', 而person02hairColor = 'black'; 實(shí)例對(duì)象重寫(xiě)原型上繼承的屬相、方法,相當(dāng)于“屬性覆蓋、屬性屏蔽”,這一操作不會(huì)改變?cè)蜕系膶傩浴⒎椒?,自然也不?huì)改變由統(tǒng)一構(gòu)造函數(shù)創(chuàng)建的其他實(shí)例,只有修改原型對(duì)象上的屬性、方法,才能改變其他實(shí)例通過(guò)原型鏈獲得的屬性、方法。

以上是“JavaScript原型和原型鏈?zhǔn)鞘裁匆馑肌边@篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI