前言
原型链是前端学习者绕不开的知识点,但坑爹的是平时的工作根本用不到,面试却又一定会问。
网上大多数教程的图和字太过抽象,背了忘,忘了背是常态。
在此记录一些我对原型链的理解,以及如何通过控制台快速了解复习原型链的方法。
本人水平有限,如有错误欢迎指正。
基础数据类型
众所众知基础数据类型有7种,而基础数据类型是没有原型链的,也就是说是什么就打印出来的就是什么,没有方法,没有原型,没有__proto__,也没有prototype。
但是,在控制台输入一些基础类型,如 true, 'string', 你会发现他们是有__proto__属性的。如下图所示:
这是因为当你访问基础数据类型的属性或方法时,JavaScript会临时将其包装为对应的对象类型,这个对象类型有原型链。这也是为什么我们可以直接调用字符串方法的原因,具体可以去了解下包装类型,在此不做过多解释。
引用数据类型
所有引用类型都有原型链。那么到底什么是原型链呢?
什么是原型链
个人简单粗暴的理解:原型链就是 通过 '__ proto __' 和 'prototype' 两个属性链接而成的一个链, 引用类型可以通过这两个属性访问到链上的所有属性。
'__ proto __' 和 'prototype' 的中文叫什么我也不知道,一般都叫原型, 原型对象,隐式原型,显式原型之类的,我至今也分不清楚,所以在此就直接用英文,反而不会弄混。
通过控制台看原型链
当在控制台输入一个引用类型时,如{}会发现在下面有个小箭头:
初看控制台输出的内容,有点像是对象中有个叫 Prototype的属性,但是输出一下,发现并不是这个意思:
在这个下面的属性,全是可以直接访问到的,其中就包括关键的__proto__属性:
可以发现打印出来的__proto__和外面观察到的[[Prototype]]一模一样,这就是原型链的关键:
当你访问一个引用对象不存在的属性时,他会在对象的__proto__属性中找同名属性。__proto__指向其构造函数的prototype属性。
可以做一个小实验去验证一下是否真的是一样的:
但是现在有个问题,当引用对象在__proto__里找不存在的属性时,其构造函数也是个对象,所以也有__proto__属性,那么就会一直向上传递,形成死循环。为了解决这个问题,js规定Object的__proto__为null, 因为所以引用对象本质上都是Object。
__ proto__找属性会向上传递,一层一层直到找到Object的__proto__,其值为null
一个例子
js中的继承就是通过原型链实现的。
在控制台中看看__proto__的搜索链:
js
class Father {
sing () {
console.log('I can sing')
}
dance () {
console.log('I can dance')
}
}
class Son extends Father {
rap () {
console.log('I can rap')
}
}
let son = new Son()
console.log('son:', son)
console.log('son.__proto__:', son.__proto__)
console.log('son.__proto__.__proto__', son.__proto__.__proto__)
console.log('son.__proto__.__proto__.__proto__', son.__proto__.__proto__.__proto__)
console.log('son.__proto__.__proto__.__proto__.__proto__', son.__proto__.__proto__.__proto__.__proto__)
总结:__ proto__ 的作用是向上搜索
再看看prototype的作用
js
Father.basketball = '篮球'
console.log('son.basketball:', son.basketball) // undefined
Father.prototype.basketball = '篮球'
console.log('son.basketball:', son.basketball) // 篮球
总结:prototype的作用是向下传递
总结
面试官: 什么是原型链?
回答:原型链是js的继承实现机制,在js中所有引用类型都有一个__proto__属性,__proto__属性指向其构造函数的prototype属性,其构造函数的prototype也是引用类型,所以也有__proto__属性,直到搜索到了Object的__proto__属性为null才停止,因此形成了一个搜索链条,我们把这个搜索链条叫做原型链。可以通俗的理解为,__proto__的作用就是向上搜索,prototype的作用为向下传递。