重新认识__proto__,prototype和constructor
-
__proto__:是任何对象在创建时都会有的属性,指向了产生当前对象的构造函数的原型对象,所谓的原型链就是由__proto__连接而成的链。它已不被推荐使用,现在更推荐使用Object.getPrototypeOf、Releft.getPrototypeOf和Object.setPrototypeOf、Reflect.setProtottypeOf。注意:
__proto__的写法,proto前后有两个英文输入的_(下划线)。 -
prototype:只有构造函数才会有的属性,指向的是当前构造函数的原型对象。 -
constructor:只有原型对象才有的属性,默认指回prototype属性所在的构造函数(指向函数本身)。JS中不管什么类型的对象,都一定有构造函数,它包括构造函数本身 接下来我们看一段代码:
function Supermarket() { }; Supermarket.prototype.product = "糖果"; function Shop() { }; Shop.prototype = new Supermarket(); Shop.prototype.drink = "可乐"; var person1 = new Shop(); var person2 = new Shop(); console.log(person1.drink);//可乐 console.log(person1.product);//糖果 console.log(person2.drink);//可乐 console.log(person2.product);//糖果在这段代码中我们可以假设一个情景: 1、我们有一个叫做Supermarket的空构造函数,然后将product属性直接加到了Supermarket的prototype属性中;
2、还有一个叫做Shop的空构造函数,然后将Supermarket构造函数加到Shop的prototype属性中,再将dirnk属性加到Shop的prototype属性中;
3、通过调用Shop这个构造函数来创建person1和person2新对象,且新对象还具有相同的属性和方法。 要求我们输出person1.dirink、person1.product、person2.dirink、person2.product,结果如下:
我们的person(也就是person1和person2)要找drink和product这俩个属性,首先实例会先在自身上找有没有这个属性,结果没有这俩个属性,就会通过__proto__找实例的原型对象,person的原型对象是Shop,我们发现Shop中有drink属性,但是却没有product属性,我们继续找Shop的原型,Shop的原型是Supermarket,我们发现Supermaket有属性product,我们要找的属性也全部找完了,就可以返回结果了。
找原型的时候我们是从底向上一步一步往上找的
我们也可以打印一下实例的__proto__和原型的prototype是否相等,如果相等,我们找的就没有问题
console.log(person1.__proto__ === Shop.prototype)
console.log(person1.__proto__.__proto__ === Supermarket.prototype)
更多关于js原型的知识点,建议看红宝书第六章。