动态

详情 返回 返回

Day 92/100 原型鏈的繼承屬性 - 动态 详情

1、JS中的繼承

當談到繼承時,JavaScript 只有一種結構:對象。每個實例對象(object)都有一個私有屬性(稱之為 proto )指向它的構造函數的原型對象(prototype)。

該原型對象也有一個自己的原型對象(__proto__),層層向上直到一個對象的原型對象為 null。根據定義,null 沒有原型,並作為這個原型鏈中的最後一個環節。

2、繼承屬性

JavaScript 對象是動態的屬性“包”(指其自己的屬性)。JavaScript 對象有一個指向一個原型對象的鏈。

當試圖訪問一個對象的屬性時,它不僅僅在該對象上搜尋,還會搜尋該對象的原型,以及該對象的原型的原型,依次層層向上搜索,直到找到一個名字匹配的屬性或到達原型鏈的末尾。

3、創建原型鏈的Demo

// 讓我們從一個函數裏創建一個對象o,它自身擁有屬性a和b的:
let f = function () {
   this.a = 1;
   this.b = 2;
}
/* 這麼寫也一樣
function f() {
  this.a = 1;
  this.b = 2;
}
*/
let o = new f(); // {a: 1, b: 2}

// 在f函數的原型上定義屬性
f.prototype.b = 3;
f.prototype.c = 4;

// 不要在 f 函數的原型上直接定義 f.prototype = {b:3,c:4};這樣會直接打破原型鏈
// o.[[Prototype]] 有屬性 b 和 c
//  (其實就是 o.__proto__ 或者 o.constructor.prototype)
// o.[[Prototype]].[[Prototype]] 是 Object.prototype.
// 最後o.[[Prototype]].[[Prototype]].[[Prototype]]是null
// 這就是原型鏈的末尾,即 null,
// 根據定義,null 就是沒有 [[Prototype]]。

// 綜上,整個原型鏈如下:

// {a:1, b:2} ---> {b:3, c:4} ---> Object.prototype---> null

console.log(o.a); // 1
// a是o的自身屬性嗎?是的,該屬性的值為 1

console.log(o.b); // 2
// b是o的自身屬性嗎?是的,該屬性的值為 2
// 原型上也有一個'b'屬性,但是它不會被訪問到。
// 這種情況被稱為"屬性遮蔽 (property shadowing)"

console.log(o.c); // 4
// c是o的自身屬性嗎?不是,那看看它的原型上有沒有
// c是o.[[Prototype]]的屬性嗎?是的,該屬性的值為 4

console.log(o.d); // undefined
// d 是 o 的自身屬性嗎?不是,那看看它的原型上有沒有
// d 是 o.[[Prototype]] 的屬性嗎?不是,那看看它的原型上有沒有
// o.[[Prototype]].[[Prototype]] 為 null,停止搜索
// 找不到 d 屬性,返回 undefined
user avatar linlinma 头像 banana_god 头像 anchen_5c17815319fb5 头像 yqyx36 头像 nznznz 头像 yangxiansheng_5a1b9b93a3a44 头像 user_ze46ouik 头像 b_a_r_a_n 头像 yanyue404 头像 tizuqiudehongcha 头像 robin_ren 头像 crow_5c1708a9c847d 头像
点赞 38 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.