您好,登錄后才能下訂單哦!
小編給大家分享一下JavaScript原型和原型鏈?zhǔn)鞘裁匆馑迹嘈糯蟛糠秩硕歼€不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
首先我們要清楚明白兩個(gè)概念:
js
分為函數(shù)對(duì)象和普通對(duì)象,每個(gè)對(duì)象都有__proto__
屬性,但是只有函數(shù)對(duì)象才有prototype
屬性Object
、Function
都是js內(nèi)置的函數(shù), 類似的還有我們常用到的Array
、RegExp
、Date
、Boolean
、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),他們有了屬性hairColor
和eat
方法;實(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)
可以看到,person01
的hairColor = 'yellow'
, 而person02
的hairColor = '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è)資訊頻道!
免責(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)容。