原型
每个js对象在创建时都会与之关联一个对象,这个对象我们称为原型,每个对象都会继承原型上的属性
prototype
每个函数都会有一个prototype属性。函数的 prototype 属性指向了一个对象,这个对象正是调用该构造函数而创建的实例的原型。
例:
构造函数
function Person () {
}
Person.prototype.name = 'test1'
let p1 = new Person()
console.log(p1.name) // test1
__proto__
每一个js对象(除null)具有的属性,这个属性指向该对象的原型
例:
function Person () {
}
let p1 = new Person()
console.log(p1.__proto__ === Person.prototype) // true
constructor
每个原型都有一个constructor属性,指向关联的构造函数
例:
function Person () {
}
let p1 = new Person()
console.log(Person === Person.prototype.constructor) // true
补充
当获取 p1.constructor 时,其实 p1 中并没有 constructor 属性,当不能读取到constructor 属性时,会从 p1 的原型也就是 Person.prototype 中读取,正好原型中有该属性,则:
p1.constructor === Person.prototype.constructor
例:
function Person () {
}
let p1 = new Person()
console.log(Person === p1.constructor) // true
实例与原型
当读取实例的属性时,找不到该属性,会查找与对象关联的原型属性,如果还查不到,会继续查原型的原型,直到查到最顶层为止。
例:
function Person () {
}
let p1 = new Person()
Person.prototype.name = 'test1'
p1.name = 'test2'
console.log(p1.name) // test2
delete p1.name
console.log(p1.name) // test1
注解:当我们删除了 p1的 name 属性时,读取 p1.name,从 p1对象中找不到 name 属性就会从 p1的原型也就是 person.__proto__ ,也就是 Person.prototype中查找,如果从 p1的原型,继续从原型的原型上找,最顶层还找不到,则为空。
以上为学习笔记总结。