浅谈原型和原型链以及instanceof的实现机制
显示原型prototype和隐式原型__proto__
以class为例:
每个类都有一个显示原型prototype,类的实例具有隐式原型__proto__指向类的prototype,类的prototype也具备一个隐式原型__proto__指向其父级的原型,这样就形成了一个原型链;具体看下方代码:
class People {
constructor (name, number) {
this.name = name
this.num = number
}
sayHi () {
console.log(`早上好${this.name}, 学号:${this.num}`)
}
}
const person1 = new People('刘备', 1212)
const person2 = new People('诸葛亮', 1213)
console.log(person1.__proto__ === People.prototype) // true
class Student extends People {
constructor (name, number) {
super(name, number)
}
eat () {
console.log('吃饭啦')
}
}
const p1 = new Student('张飞', 1209)
const p2 = new Student('赵云', 1200)
console.log(p1.__proto__ === Student.prototype, p1.prototype === Student.prototype) // true false
console.log(p1.prototype === p2.prototype, '实例原型比较') // true
console.log(p1.__proto__ === p2.__proto__) // true 两个实例的隐式原型同时指向Student的显示原型
console.log(p1.__proto__ === People.prototype, p1.__proto__ === Object.prototype) // false 实例的隐式原型指向的是父级类,没有指向父级以上的类原型
console.log(Student.prototype.__proto__ === People.prototype) // true 类的原型的隐式原型指向父级类的原型,这个可类比实例的隐式原型
p1.eat()// 吃饭啦
instanceof可用于判断数据的类型,与typeof相比较,instanceof能够细分引用类型数据的具体类型,比如Array;instanceof的实现原理就是沿着数据的原型链查找原型类型;下面代码详细展示了instanceof在原型链上的查找过程:
/**
* instanceof实现原理:
* 下面代码展示了instanceof实现判断数据类型的流程,
* instanceof沿着数据的原型链一级一级往上找,最后一个
* 判断是否为Array的返回false是由于再p1的原型链上没有Array
*/
console.log(p1 instanceof Student) // true
console.log(p1 instanceof People) // true
console.log(p1 instanceof Object) // true
console.log(p1 instanceof Array) // false