首頁  >  文章  >  web前端  >  圖文詳解JavaScript原型鏈

圖文詳解JavaScript原型鏈

WBOY
WBOY轉載
2022-03-15 17:50:433121瀏覽

本篇文章為大家帶來了關於javascript的相關知識,其中主要介紹了關於原型鏈的相關問題,原型鏈指一些原型透過__proto__指標構成的鍊錶,一個原型鏈可以為想共享原型鏈中資料的物件服務,希望對大家有幫助。

圖文詳解JavaScript原型鏈

相關推薦:javascript教學

#1.原型鏈

1.1 原型鏈解釋:

  1. (概念) 原型鏈指一些原型透過__proto__指標構成的鍊錶,一個原型鏈可以為想共享原型鏈中資料的物件服務,用於實現JavaScript中的繼承機制。

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

    • 每個物件都有一個__proto__指標來存取物件的原型
    • 每個原型都是一個用來實現繼承的對象,除了有__proto__指標之外,還有constructor指標指向建構函式
    • 每個函式都是一個對象,除了有__proto__指針之外,還有prototype指針指向與之關聯的原型對象,prototype的指向和__proto__指向不一定相同。

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

  1. 建構子類型原型鏈:原型鏈服務的物件由建構子產生(這張圖非常重要,涉及了底層的鏈,網路上也有類似的圖)
#
function A() {

}
let a1 = new A()
let a2 = new A()
let a3 = new A()
// 这几行代码会产生下面图示的原型链

圖文詳解JavaScript原型鏈

  1. 非建構子類型原型鏈:原型鏈服務的物件由工廠函數,物件字面量,Object.create等方式產生
let A = {
    test: ""
}
let a1 = Object.create(A)
let a2 = Object.create(A)
let a3 = Object.create(A)
// 这几行代码对应下面图示的原型链

圖文詳解JavaScript原型鏈

  1. 簡化的原型鏈:實際考慮原型鏈時往往不需要考慮“建構函式Function的實例對應的原型鏈”,甚至"原型鏈終點"和"Object.prototype"都不需要考慮。因為涉及複雜的繼承關係時考慮這些偏底層的內容不利於分析。 一般分析時使用下面的兩個簡化圖分析即可。
function A() {

}
let a1 = new A()
let a2 = new A()
let a3 = new A()
// 这几行代码会产生下面图示的原型链

圖文詳解JavaScript原型鏈

1.3 涉及繼承的原型鏈圖示

#涉及繼承的原型鏈使用簡化圖分析即可

// 使用寄生组合模式实现继承
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 原型鏈終點

原型鏈的終點是null,並不是指某個原型物件

1.5 原型的動態性

原型的動態性在「物件導向程式設計」中詳細解釋過,主要涉及的是原型的重寫和修改。這裡列舉幾個例題。
範例1—原型的動態性

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—原型的動態性&原型鏈底層鏈

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

參考上述提到的「不涉及繼承的原型鏈圖示」中的第一幅圖可以畫出如下簡化參考圖分析問題。
圖文詳解JavaScript原型鏈

範例3—原型動態性&原型鏈底層鏈

function Person(name) {
    this.name = name
}
let p = new Person('Tom');
console.log(p.__proto__) //  Person.prototype
console.log(Person.__proto__) // Function.prototype

範例4—原型動態性&原型鏈底層鏈

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

參考上述提到的「不涉及繼承的原型鏈圖示」中的第一幅圖可以畫出如下簡化參考圖分析問題。 由於foo和F宣告時它們就將自己的原型進行綁定,它們透過堆疊記憶體中儲存的指標來取得堆疊記憶體中儲存的原型的位址。首先進行了原型的修改操作,修改操作會在堆疊記憶體上修改原型,foo和F透過堆疊記憶體的指標仍然可以存取到修改後的結果。第二步進行了原型的重寫,JS都是“傳值操作”,重寫原型後,首先在堆內存中開闢一塊新空間存儲新的原型,然後在棧內存重新開闢一個空間存儲指向堆內存的指針。此時由於foo和F所持有的堆疊記憶體指標和新的堆疊記憶體指標不同,所以foo和F無法存取到重寫後的原型。
圖文詳解JavaScript原型鏈

相關推薦:javascript學習教學

#

以上是圖文詳解JavaScript原型鏈的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除