讲解一下关于原型链的知识。
instanceof
语法:
1  | object instanceof constructor;  | 
instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
简单来说就是检查constructor.prototype是否出现在object.__proto__上面。
注意:这个对比的不是输入时的参数,而是他们的原型,这也是和isPrototypeOf的区别
听起来是不是很奇怪?为什么是
constructor.prototype是否出现在object.__proto__上面,而不是object.__proto__出现在constructor.prototype上面?
大家都知道这个是用来判断继承或者一个实例是否是某个类的。
这就要想清楚继承的真正含义,别被想当然给误解了。
类 A 继承 Z,那么 A 的实例 a 应该都“属于”A 和 Z,也就是 instaceof 都是 true。继承其实是子类包含父类,而不是父类包含子类。
那为什么说子类属于父类呢?
这个是从不同概念上来说的,子类属于父类是从抽象的概念上来说的,上面说的包含是从内容上面来说。比如男人女人都属于人类,但是男人包含了所有人类这个层面抽象的所有内容。
1  | 从抽象概念上说:子类是父类的一部分,属于父类。  | 
isPrototypeOf
isPrototypeOf() 方法用于测试一个对象是否存在于另一个对象的原型链上。
1  | prototypeObj.isPrototypeOf(object)  | 
检测prototypeObj是否在object的原型链上。
注意:这个做对比时,就是
prototypeObj本身,而不是他的原型,这是和instanceof的区别。写是o,那对比的就是o,写的是o.__proto__,对比的就是o.__proto__
1  | function C(){}  | 
Object.create
1  | let o=Object.create(proto[, propertiesObject])  | 
Object.create()方法创建一个新对象o,使用现有的对象proto来提供新创建的对象o的__proto__。
Object.getPrototypeOf
Object.getPrototypeOf() 方法返回指定对象的原型(内部[[Prototype]]属性的值)
1  | let proto = Object.getPrototypeOf(object);  | 
proto就是object的__proto__
new 运算符
new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。new 关键字会进行如下的操作:
- 创建一个空的简单 JavaScript 对象(即{});
 - 链接该对象(即设置该对象的构造函数)到另一个对象 ;
 - 将步骤 1 新创建的对象作为 this 的上下文 ;
 - 如果该函数没有返回对象,则返回 this。
 
1  | function Car() {  | 
因为函数有自己的返回值,所以实例化的对象就是返回的对象,而不是 this;
1  | function Car(name) {  | 
这里解释为什么car2的name有值,car3没有;
首先要明白new运算符的执行过程;从上面定义我们知道,创建的car1是有属性name的,car1的__proto__是指向Car.prototype,这上面是没有name的。
然后需要明白Object.create的使用,它是把创建的对象的__proto__指向了传入的对象。
因此car2.__proto__===car1,因此有name属性;car3.__proto__指向car1.__proto__也就是Car.prototype,所以没有name属性。

