溫馨提示×

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

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

JavaScript原型鏈指的是什么

發(fā)布時(shí)間:2022-03-16 09:35:39 來(lái)源:億速云 閱讀:260 作者:小新 欄目:web開發(fā)

這篇文章主要為大家展示了“JavaScript原型鏈指的是什么”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“JavaScript原型鏈指的是什么”這篇文章吧。

1.原型鏈

1.1 原型鏈解釋:

  1. (概念) 原型鏈指一些原型通過(guò)__proto__指針構(gòu)成的鏈表,一個(gè)原型鏈可以為想共享原型鏈中數(shù)據(jù)的對(duì)象服務(wù),用于實(shí)現(xiàn)JavaScript中的繼承機(jī)制。

  2. (原型鏈指針) 原型鏈中涉及到的指針:

    • 每個(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__指向不一定相同。

1.2 不涉及繼承的原型鏈圖示:

  1. 構(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)生下面圖示的原型鏈

JavaScript原型鏈指的是什么

  1. 非構(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)下面圖示的原型鏈

JavaScript原型鏈指的是什么

  1. 簡(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)生下面圖示的原型鏈

JavaScript原型鏈指的是什么

1.3 涉及繼承的原型鏈圖示

涉及繼承的原型鏈?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()

JavaScript原型鏈指的是什么

1.4 原型鏈終點(diǎn)

原型鏈的終點(diǎn)是null,并不是指某個(gè)原型對(duì)象

1.5 原型的動(dòng)態(tài)性

原型的動(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)題。
JavaScript原型鏈指的是什么

例題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原型鏈指的是什么

以上是“JavaScript原型鏈指的是什么”這篇文章的所有內(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