前端百题斩【017】——一基础、二主线、双机制理解原型链

写该系列文章的初衷是“让每位前端工程师掌握高频知识点,为工作助力”。这是前端百题斩的第17斩,希望朋友们关注公众号“执鸢者”,用知识武装自己的头脑。

17.1 基础

在js中,每一个对象都包含一个原型属性,用于关联另一个对象,关联后就能够使用那个对象的属性和方法;对象之间通过原型关联到一起,就好比用一条锁链将一个个对象连接在一起,在与各个对象挂钩后,最终形成了一条原型链。(注意:js中的对象分为函数对象和普通对象,这两类对象均具备__ proto __属性,但是只有函数对象才有prototype属性。)

17.2 原型链流程

下图是网上流传的学习原型链的一幅神图,我们先贴出来一点一点分析。

img
17.2.1 普通对象

js对象中的一种类型是普通对象,上述图中的一条主线也是根据普通对象来的,下面通过一段代码来演示一下。

const obj = {
    a: 10,
    b: 20
};

console.log(obj);
console.log(obj.__proto__);
console.log(obj.__proto__.__proto__);
console.log(obj.__proto__.constructor);
console.log(obj.__proto__.constructor.__proto__);
console.log(obj.__proto__.constructor.__proto__.__proto__);
console.log(obj.__proto__.constructor.__proto__.constructor);
console.log(obj.__proto__.constructor.__proto__.constructor.__proto__);

上述的打印结果如下所示,其打印结果与上述普通对象的链路完全一致。

image-20210530172247273.png
17.2.2 函数对象

js对象中的一种类型是函数对象,上述图中的一条主线也是根据函数对象来的,下面通过一段代码来演示一下。

function fun() {
    let a = 12;
}

console.log(fun);
console.log(fun.__proto__);
console.log(fun.__proto__.__proto__);
console.log(fun.__proto__.__proto__.__proto__);
console.log(fun.__proto__.constructor);
console.log(fun.__proto__.constructor.__proto__);
console.log(fun.__proto__.constructor.__proto__.__proto__);
console.log(fun.__proto__.constructor.__proto__.__proto__.__proto__);

上述的打印结果如下所示,其打印结果与上述函数对象的链路完全一致。

image-20210606131621751.png

17.3 两个机制

上述讲述了原型链的定义及其流程,那么对于其上的属性是按照什么流程查找和修改该的呢?

17.3.1 属性查找机制

当查找对象的属性时,如果实例对象自身不存在该属性,则沿着原型链往上一级查找,找到时则输出,不存在时,则继续沿着原型链往上一级查找,直至最顶级的原型对象Object.prototype,如还是没找到,则输出undefined;

const obj1 = {
    a: 10
};

const obj2 = {
    b: 20
};

Object.setPrototypeOf(obj2, obj1);

// 由于obj2自身不存在a属性,但是其原型obj1上存在,所以输出其上的值10;
console.log(obj2.a); // 10
// 由于b属性在obj2本身,输出20;
console.log(obj2.b); // 20
// c属性在obj2和其原型上都不存在,则输出undefined。
console.log(obj2.c); // undefined
17.3.2 属性修改机制

只会修改实例对象本身的属性,如果不存在,则进行添加该属性,如果需要修改原型的属性时,则可以用: b.prototype.x = 2;但是这样会造成所有继承于该对象的实例的属性发生改变。

const obj1 = {
    a: 10
};

const obj2 = {
    b: 20
};

Object.setPrototypeOf(obj2, obj1);

console.log(obj2); // {b: 20}
console.log(obj1); // {a: 10}
obj2.b = 30;
obj2.a = 50;
// 修改b属性生效,修改a属性在其本身添加了a属性
console.log(obj2); // { b: 30, a: 50 }
console.log(obj1); // { a: 10 }
obj2.__proto__.a = 20;
// 直接修改原型上属性生效
console.log(obj1); // { a: 20 }

1.如果觉得这篇文章还不错,来个分享、点赞、在看三连吧,让更多的人也看到~

2.关注公众号执鸢者,领取学习资料,定期为你推送原创深度好文

3.关注公众号进群,里面大佬多多,一起向他们学习

1. 前端百题斩[001]——typeof和instanceof

2. 前端百题斩【002】——js中6种变量声明方式

3. 前端百题斩【003-004】——从基本类型、引用类型到包装对象

4. 前端百题斩【005】—— js中9种遍历对象的方法

5. 前端百题斩【006】——js中三类字符串转数字的方式

6. 前端百题斩【007】——js中必须知道的四种数据类型判断方法

7. 前端百题斩【008-009】——从JavaScript的代码执行过程到函数执行过程

8. 前端百题斩【010】——通俗易懂的JavaScript执行上下文

9. 前端百题斩【011】——通俗易懂的变量对象

10. 前端百题斩【012】——js中作用域及作用域链的真面目

11. 前端百题斩【013】——用“闭包”问题征服面试官

12. 前端百题斩【014】——js中的这些“this”指向都值得了解

13. 前端百题斩【015】——快速手撕call、apply、bind

14. 前端百题斩【016】——原型、构造函数和实例之间的奇妙关系

15. 十七张图玩转Node进程——榨干它

16. 理论与API相结合理解Node中的网络通信

17. 一文彻底搞懂前端监控

18. 前端的葵花宝典——架构

19. canvas从入门到猪头

20. 前端工程师的一大神器——puppeteer

21. 2021 年前端宝典【超三百篇】

22. 前端也要懂机器学习(上)

23. 前端也要懂机器学习(下)

24. 学架构助力前端起飞

25. 假如只剩下canvas标签

26. Vue源码思想在工作中的应用

27. 一文搞定Diff算法

28. 百度、小红书三面,均遇“赛马”问题

29. 十五张图带你彻底搞懂从URL到页面展示发生的故事

30. 一文搞懂Cookie、Storage、IndexedDB

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值