您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“JavaScript原型鏈指的是什么”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“JavaScript原型鏈指的是什么”這篇文章吧。
(概念) 原型鏈指一些原型通過(guò)__proto__指針構(gòu)成的鏈表,一個(gè)原型鏈可以為想共享原型鏈中數(shù)據(jù)的對(duì)象服務(wù),用于實(shí)現(xiàn)JavaScript中的繼承機(jī)制。
(原型鏈指針) 原型鏈中涉及到的指針:
每個(gè)對(duì)象都有一個(gè)__proto__指針來(lái)訪問(wèn)對(duì)象的原型
每個(gè)原型都是一個(gè)用于實(shí)現(xiàn)繼承的對(duì)象,除了有__proto__指針之外,還有constructor指針指向構(gòu)造函數(shù)
每個(gè)函數(shù)都是一個(gè)對(duì)象,除了有__proto__指針之外,還有prototype指針指向與之關(guān)聯(lián)的原型對(duì)象,prototype的指向和__proto__指向不一定相同。
構(gòu)造函數(shù)類型原型鏈:原型鏈服務(wù)的對(duì)象由構(gòu)造函數(shù)產(chǎn)生 (這張圖非常重要,涉及了底層的鏈,網(wǎng)上也有類似的圖)
function A() { } let a1 = new A() let a2 = new A() let a3 = new A() // 這幾行代碼會(huì)產(chǎn)生下面圖示的原型鏈
非構(gòu)造函數(shù)類型原型鏈:原型鏈服務(wù)的對(duì)象由工廠函數(shù),對(duì)象字面量,Object.create等方式產(chǎn)生
let A = { test: "" } let a1 = Object.create(A) let a2 = Object.create(A) let a3 = Object.create(A) // 這幾行代碼對(duì)應(yīng)下面圖示的原型鏈
簡(jiǎn)化的原型鏈:實(shí)際考慮原型鏈時(shí)往往不需要考慮“構(gòu)造函數(shù)Function的實(shí)例對(duì)應(yīng)的原型鏈”,甚至"原型鏈終點(diǎn)"和"Object.prototype"都不需要考慮。因?yàn)樯婕暗綇?fù)雜的繼承關(guān)系時(shí)考慮這些偏底層的內(nèi)容不利于分析。一般分析時(shí)使用下面的兩個(gè)簡(jiǎn)化圖分析即可。
function A() { } let a1 = new A() let a2 = new A() let a3 = new A() // 這幾行代碼會(huì)產(chǎn)生下面圖示的原型鏈
涉及繼承的原型鏈?zhǔn)褂煤?jiǎn)化圖分析即可
// 使用寄生組合模式實(shí)現(xiàn)繼承 function C() {} function B() {} B.prototype = new C() function A() {} A.prototype = new B() let a1 = new A() let a2 = new A() let a3 = new A()
原型鏈的終點(diǎn)是null,并不是指某個(gè)原型對(duì)象
原型的動(dòng)態(tài)性在“面向?qū)ο缶幊獭敝性敿?xì)解釋過(guò),主要涉及的是原型的重寫和修改。這里列舉幾個(gè)例題。
例題1—原型的動(dòng)態(tài)性
var A = function() {}; A.prototype.n = 1; var b = new A(); A.prototype = { n: 2, m: 3 } var c = new A(); console.log(b.n); // 1 console.log(b.m); // undefined console.log(c.n); // 2 console.log(c.m); // 3
例題2—原型的動(dòng)態(tài)性&原型鏈底層鏈
var F = function() {}; Object.prototype.a = function() { console.log('a'); }; Function.prototype.b = function() { console.log('b'); } var f = new F(); f.a(); // a f.b(); // 并不存在b屬性 F.a(); // a F.b(); // b
參考上述提到的“不涉及繼承的原型鏈圖示”中的第一幅圖可以畫出如下簡(jiǎn)化參考圖分析問(wèn)題。
例題3—原型動(dòng)態(tài)性&原型鏈底層鏈
function Person(name) { this.name = name } let p = new Person('Tom'); console.log(p.__proto__) // Person.prototype console.log(Person.__proto__) // Function.prototype
例題4—原型動(dòng)態(tài)性&原型鏈底層鏈
var foo = {}, F = function(){}; Object.prototype.a = 'value a'; Function.prototype.b = 'value b'; Object.prototype = { a: "value a" } Function.prototype = { b: "value b" } console.log(foo.a); // value a console.log(foo.b); // undefined console.log(F.a); // value a console.log(F.b); // value b
參考上述提到的“不涉及繼承的原型鏈圖示”中的第一幅圖可以畫出如下簡(jiǎn)化參考圖分析問(wèn)題。由于foo和F聲明時(shí)它們就將自己的原型進(jìn)行綁定,它們通過(guò)棧內(nèi)存中存儲(chǔ)的指針獲取堆內(nèi)存中存儲(chǔ)的原型的地址。首先進(jìn)行了原型的修改操作,修改操作會(huì)在堆內(nèi)存上修改原型,foo和F通過(guò)棧內(nèi)存的指針仍然可以訪問(wèn)到修改后的結(jié)果。第二步進(jìn)行了原型的重寫,JS都是“傳值操作”,重寫原型后,首先在堆內(nèi)存中開辟一塊新空間存儲(chǔ)新的原型,然后在棧內(nèi)存重新開辟一個(gè)空間存儲(chǔ)指向堆內(nèi)存的指針。此時(shí)由于foo和F持有的棧內(nèi)存指針和新的棧內(nèi)存指針不同,所以foo和F無(wú)法訪問(wèn)到重寫后的原型。
以上是“JavaScript原型鏈指的是什么”這篇文章的所有內(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)容。