概念
参考:http://www.ruanyifeng.com/blog/2011/06/designing_ideas_of_inheritance_mechanism_in_javascript.html 或 https://www.jianshu.com/p/be7c95714586
一、__proto__:
1、每一个JavaScript对象(除了 null )都具有的一个属性,叫__proto__,这个属性会指向该对象的原型【实例对象的原型 就是 构造函数的prototype属性】。即
function Person() { } var person = new Person(); console.log(person.__proto__ === Person.prototype); // true ,即 实例对象的 __proto__属性指向 构造 构造函数 的 prototype 属性
注意:__proto__就是对象 指向 构造函数 的prototype 属性的指针,在es5 中这个指针被称为对象的原型。我们最好不要使用这个属性,因为它不是规范中规定的。
es5 中 新增了一个 Object.getPrototypeof() 方法,我们可以通过这个方法来获取对象的原型。
二、prototype:
1、每个函数 都有一个 prototype 属性。这个属性是类给实例对象 继承使用的。
虽然每个函数都有prototype 属性,但是只有只有构造函数的prototype 才有意义。普通函数 不创建 实例对象,就不会有实例对象去访问 prototype 里面的 属性、方法。
每一个JavaScript对象(null除外)在创建的时候就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型"继承"属性。
2、构造函数 的 prototype 属性就是 实例对象的 原型。
function Person() { } var person = new Person(); console.log(person.__proto__ === Person.prototype); // true ,即 实例对象的 __proto__属性指向 构造 构造函数 的 prototype 属性
三、constructor:
1、每个原型都有一个 constructor 属性指向关联的构造函数。【实例的原型就是 构造函数 的prototype 属性】
function Person () { } const person1 = new Person() console.log(Person === Person.prototype.constructor) // true ,实例原型的 constructor 属性指向的 就是 构造函数。 console.log(person1.__proto__.constructor === Person) // true ,实例原型的 constructor 属性指向的 就是 构造函数。
注意:用构造函数生成实例对象,构造函数内(注意是函数里面)的属性、方法会生成一个副本,无法共享属性和方法。所以才 为构造函数发明了 prototype 属性,来解决这个问题。
所有实例对象需要共享的属性和方法,都放在这个对象里面;那些不需要共享的属性和方法,就放在构造函数里面。
四、原型和原型链:https://www.jianshu.com/p/7d58f8f45557
1、js中 实例对象、构造函数 都是 对象,所以他们都有对应的 原型,即 __proto__ 属性。
2、实例对象原型 指向 父类(构造函数)的 prototype属性。父类的原型 指向 它的 父类 的 prototype 属性。这样一直 延续下去,直到最后一个对象的原型指向 null 时,原型链才结束。