一、原型
- 所有引用类型都有一个__proto__(隐式原型)属性,属性值是一个普通的对象
- 所有函数都有一个prototype(原型)属性,属性值是一个普通的对象
- 所有引用类型的__proto__属性指向它构造函数的prototype
二、原型链
访问一个对象的某个属性时,
- 先在这个对象本身属性上查找
- 如果没有找到,则会去它的__proto__隐式原型上查找,即它的构造函数的prototype
- 如果还没有找到就会再在构造函数的prototype 的 __proto__中查找
这样一层一层向上查找就会形成一个链式结构,我们称为原型链。
不懂没关系,直接看代码!!! (红色字往死里记)
class Person {}
let ming = new Person()
console.log(ming.__proto__ == Person.prototype) //true
console.log(Person.__proto__ == Function.prototype) //true
console.log(Function.__proto__ == Function.prototype) //true
console.log(ming.constructor == Person) //true
console.log(Person.constructor == Function) //true
console.log(Function.constructor == Function) //true
对象的原型永远指向其构造函数的原型对象!!!
console.log(ming.constructor == Person) //true
console.log(ming.__proto__.constructor == Person) //true
console.log(Person.prototype.constructor == Person) //true
实例对象本身没有constructor属性,是通过实例对象的原型查找的!所以实例对象、实例对象的原型以及构造函数的原型对象的constructor都指向构造函数!!!
console.log(ming.__proto__ == Person.prototype) //true
console.log(Person.prototype.__proto__ == Object.prototype) //true
console.log(Object.prototype.__proto__ == null) //true
console.log(ming.__proto__.constructor == Person) //true
console.log(Person.prototype.__proto__.constructor == Object) //true
原型链的查找方式:ming => ming.__proto__ => ming.__proto__.__proto__(Person.prototype.__proto__) => ming.__proto__.__proto__.__proto__(Object.prototype.__proto__) = null
因为函数的原型对象是个对象,是顶级对象(Object)构建出来的,所以原型对象的原型指向顶级对象(Object)的原型对象
console.log(Object.__proto__ == Function.prototype) //true
console.log(Object.prototype.__proto__ == null) //true
console.log(Function.prototype.__proto__.constructor == Object) //true
console.log(Function.prototype.__proto__ == Object.prototype) //true