原型
理解原型之前我们要知道什么是原型?js中万物皆对象,因此原型也是对象,可以通过原型实现对象属性的继承。
什么是原型对象?
“我们创建的每个函数都有一个prototype(原型)属性(除了Function.bind()返回的函数),这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。”
–摘自人民邮电出版社出版的Nicholas C.Zakas著的《JavaScript高级程序设计》(第2版)
因此,prototype(原型)属性指向的对象就是原型对象。
然后咱们需要了解这几个属性
constructor:是不影响任何JavaScript的内部属性。一般来说对象的constructor属性指向其构造函数,但是._proto_=== .constructor.prototype是不完全正确的。
_proto_(隐式原型)与prototype(显式原型):几乎任何对象有一个[[prototype]]属性,也就是现在的_proto_,在标准中,这是一个隐藏属性。该属性指向的是创建这个对象的函数(constructor)的原型(prototype)
有三种创建对象的方法
1、通过对象字面量构造出来的对象
var person1 = {
name: 'wtc',
sex: 'man'
};
这样子构造出的对象,其_proto_指向Object.prototype
2、通过构造函数构造出来的对象
function Person(){
name: 'wtc',
sex: 'man'
}
var person1 = new Person();
通过new操作符实例化的函数就是构造函数。由构造函数构造的对象,其_proto_指向其构造函数的prototype属性指向的对象。每个函数都有一个prototype属性(除了Function.bind()返回的函数),其所指向的对象带有constructor属性,这一属性指向函数自身。(在本例中,person1的_proto_指向Person.prototype)
3、通过函数Object.create()创建对象
var person1 = {
name: 'wtc',
sex: 'man'
};
var person2 = Object.create(person1);
通过这种方式创建出来的对象 person2._proto_ 指向的就是person1对象
在ES5中我们可以通过Object.getPrototypeOf获取一个对象的_proto_ ,在ES6中我们可以通过Object.setPrototypeOf设置一个对象的_proto_
instanceof:该 操作符的内部实现机制和隐式原型、显式原型有直接的关系。instanceof的左值一般是一个对象,右值一般是一个构造函数,用来判断左值是否是右值的实例。它的内部实现原理是这样的:
// L instanceof R
//通过判断
L.__proto__.__proto__ ..... === R.prototype
//最终返回true or false
就是沿着对象L的_proto_一直寻找到原型链末端,直到等于R.prototype为止。
Function instanceof Object // true
Object instanceof Function // true
Function instanceof Function //true
Object instanceof Object // true
Number instanceof Number //false
最后贴上一张经典的图(理解的还不够深,有其他见解的欢迎留言)