# 原型与原型链

# 1、prototype

每个函数都有prototype属性,只有函数有该属性。该属性指向了一个对象,这个对象是调用该构造函数而创建的实例的原型。 简单来说,每一个js对象(null除外)在创建的时候会与之关联另一个对象,这个对象就是原型,每一个对象都会从原型继承属性。

function Person(){
}
Person.prototype.name = 'test';
const person1 = new Person();
console.log(person1.name) //test

# 2、proto

每个js对象都具有的属性,proto,这个属性指向该对象的原型。

function Person(){

}
const person = new Person();
console.log(person.__proto__ === Person.prototype) //true

# 3、constructor

如果说prototype是构造函数指向原型,proto是实例对象指向原型,那么constructor就是指向构造函数。

function Person(){
}
console.log(Person === Person.prototype.constructor) //true

es5也有获取对象原型的方法

function Person(){
}
const person = new Person()
console.log(Object.getPrototypeof(person) === Person.prototype) //true

# 4、原型链

在读取实例的属性时,如果找不到,就会找实例的原型。如果还找不到,就找原型的原型,一直找到最顶层为止。如上例,会先找person、Person.prototype、Object.prototype。而Object.prototype.__proto__就为null了。即Object.prototype对象没有原型。所以查找属性的时候,找到Object.prototype就停止了。

# 5、注意

(1)由于constructor是原型指向构造函数的,而实例又可以通过proto属性指向原型,所以实例也可以通过constructor指向构造函数。

person.constructor === Person.prototype.constructor //true

(2)关于继承 继承意味着复制操作,而js对象并不会复制对象的属性,而是在两个对象之间创建一个关联,这样,一个对象就可以通过委托访问另一个对象的属性和函数。