面试高频:原型链 - prototype & __proto__深入了解
开源
个人开源的leno-admin
后台管理项目,前端技术栈:reactHooks
、ant-design
;后端技术栈:koa
、mysql
、redis
,整个项目包含web端
、electron客户端
、mob移动端
、template基础模板
,能够满足你快速开发一整套后台管理项目;如果你觉得不错,就为作者点个✨star
✨吧,你的支持就是对我最大的鼓励;
什么是原型?
几乎每个对象JavaScript对象都有另一个与之关联的对象。这另一个对象被称为原型(prototype),第一个对象从这个原型继承属性。
-- 《JavaScript权威指南》
前言
原型链相信是每一个成为前端工程师必须逾越过去的高山,很多专业的书籍讲解的原型链经过翻译之后也是晦涩难懂,初学者很难理解;
故此发表文章,在此简单的梳理下原型链到底是怎样一层关系,最后奉上两道基础的原型链的习题,如若有不对之处,欢迎各位指正;
prototyp与__proto__ 🥬🥬
叫什么?
- prototype => 显示原型
- __proto__ => 隐式原型
特性一
复杂数据类型都有隐式原型__proto__属性:
const arr = [];
const obj = [];
const fun = function () {};
console.log(arr.__proto__);
console.log(obj.__proto__);
console.log(fun.__proto__);
特性二
复杂数据类型,都有obje的特性:
const arr = []
const obj = []
const fun = function () {}
arr.v = 11
obj.v = 11
fun.v = 11
console.log(arr.v) // => 11
console.log(obj.v) // => 11
console.log(fun.v) // => 11
这个特性我们在日常代码中几乎每时每刻都存在,奇视arr、fun、RegExp本质上都是对象;
特性三
复杂数据类型的__proto__的属性值指向它的构造函数的prototype的属性值:
const arr = [];
const obj = {};
const fn = function () {};
console.log(arr.__proto__ === Array.prototype); // => true
console.log(obj.__proto__ == Object.prototype); // => true
console.log(fn.__proto__ == Function.prototype); // => true
特性四
当一个对象的某个属性没有时,它会顺着它的__proto__(也是它的构造函数的prototype)里去寻找属性:
const obj = {}
console.log(obj.hasOwnProperty) // => ƒ hasOwnProperty() { [native code]
obj对象我们并没有给他赋任何值,他身上是没有hasOwnProperty这个属性的,之所以能够打印出来,是因为obj的__proto__属性是从Object.prototype身上取的;
instanceof 🌰🥕
instanceof
运算符用于检测构造函数的 prototype
属性是否出现在某个实例对象的原型链上;
function Fun(v) {
this.v = v;
}
let obj = new Fun("11");
console.log(obj instanceof Fun); // => true
console.log(obj instanceof Object); // => true
obj instanceof Fun 相等,是因为obj的__proto__ 等于 Fun.prototype;
obj instanceof Object相等,是因为原型链;
console.log(obj.proto === Fun.prototype); // => true
console.log(Fun.prototype.proto === Object.prototype); // => true
原理图 🥝🍎
习题练习 🍤🦪
案例一
// 执行后,a.x & b.x 的结果分别是?
function A(x) {
this.x = x;
}
A.prototype.x = 1;
function B(x) {
this.x = x;
}
B.prototype = new A();
let a = new A(2),
b = new B(3);
delete b.x;
console.log(a.x, b.x); // => 2, undefined
案例二
// JS 代码输出的是什么?
function father() {
this.num = 935;
this.work = ["read", "write", "listen"];
}
function son() {}
son.prototype = new father();
let son1 = new son();
let son2 = new son();
son1.unm = 17;
son1.work.pop();
console.log(son2.num);
console.log(son2.work);
console.log(son2.num); // => 935
console.log(son2.work); // => ['read','write']
总结
原型链其实就是执行一件事的一个过程,就像串联的东西一样,连在一起,贯穿整个原型链;