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

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

640.jpg

17.1 基础



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


17.2 原型链流程



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

640.jpg



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__);

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

640.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__);


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


640.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 }


相关文章
|
7月前
|
存储 前端开发 JavaScript
第六章(原理篇) 微前端间的通信机制
第六章(原理篇) 微前端间的通信机制
162 0
|
7月前
|
存储 前端开发 JavaScript
深入理解前端JavaScript执行机制
深入理解前端JavaScript执行机制
76 0
|
7月前
|
前端开发 安全 JavaScript
前端开发中的跨域资源共享(CORS)机制
【2月更文挑战第3天】 在前端开发中,跨域资源共享(CORS)机制是一个重要的安全性问题。本文将介绍CORS的概念、原理和实现方式,并探讨在前端开发中如何处理跨域资源请求,以及如何提高网站的安全性。
|
4月前
|
前端开发 JavaScript
彻底理解前端原型链
【8月更文挑战第14天】彻底理解前端原型链
48 0
|
3月前
|
前端开发 JavaScript C++
详解链表在前端的应用,顺便再弄懂原型和原型链!
该文章深入解析了链表在前端开发中的应用,并详细阐述了JavaScript中的原型和原型链的概念及其工作原理。
|
4月前
|
前端开发 JavaScript
前端必修之一 彻底理解原型和原型链
【8月更文挑战第2天】理解原型和原型链
76 11
|
7月前
|
前端开发 JavaScript
前端 js 经典:原型对象和原型链
前端 js 经典:原型对象和原型链
43 1
|
7月前
|
前端开发
前端路由机制实现hash-history
前端路由机制实现hash-history
45 1
|
7月前
|
前端开发 JavaScript
【Web 前端】什么是原型链?
【4月更文挑战第22天】【Web 前端】什么是原型链?
|
7月前
|
开发框架 前端开发 Android开发
【Flutter 前端技术开发专栏】Flutter 与原生模块通信机制
【4月更文挑战第30天】本文探讨了Flutter作为跨平台开发框架与原生Android和iOS交互的必要性,主要通过方法调用和事件传递实现。文中详细介绍了Flutter与Android/iOS的通信方式,数据传输(包括基本和复杂类型),性能优化,错误处理以及实际应用案例。理解并掌握这一通信机制对开发高质量移动应用至关重要,未来有望随着技术发展得到进一步优化。
78 0
【Flutter 前端技术开发专栏】Flutter 与原生模块通信机制