首先,先介绍一个今天的主角:proto(隐式原型)与prototype(显式原型)javascript
prototype(显式原型)
在每个函数(请注意是函数)建立以后都会有一个叫prototype的属性,这个属性指向的是函数的原型对象。java
__proto__(隐式原型)
javascript 中任意对象都具备一个内置属性,在ES5以前并无标准的方法访问这个属性,可是在绝大多数浏览器中都支持经过__proto__来访问这个属性,咱们叫他隐式原型浏览器
首先咱们来看一个例子:函数
function Foo(){} var foo = new Foo(); foo.__proto__ === Foo.prototype; //=>true
由上面咱们能够看出函数foo的隐式原型指向其构造函数的显式原型.this
经过这个咱们能得出一个这样的结论么:
某对象(万物皆对象).__proto__ === 其构造函数.prototype么,
答案是否认的,咱们来看如下例子:prototype
let obj = {name: 'zarr'}; let sonObj = Object.create(obj); console.log(sonObj.name); //=>zarr console.log(sonObj.__proto__ === obj.prototype) //=>false console.log(sonObj.__proto__ === obj) //=>true
ok,咱们再看一个例子code
var Obj = { a: 13 }; var obj = Object.create(Obj); console.log(obj.a); //=>13 console.log(obj.__proto__ === Obj) //=>true var Func = function () { this.a = 'ds'; } var func = Object.create(Func); console.log(func.__proto__ === Func.prototype) //=>false console.log(func.__proto__ === Func) //=>true console.log(func.a) //undefined
不是说一个对象的隐式原型等于起构造函数的原型? 为何这个时候又等于这个构造函数了?
这就要分析一下Object.create的实现了,其实实现起来也不难,你们看下面对象
Object.create = function(obj){ function f() {} f.prototype = obj; return new f(); }
这下明朗了, 经过Object.create构造出的对象其实仍是new出来的对象,好比上例的var func = Object.create(Func); func.__proto__ === f.prototype === Func,
func.__proto__ === f.prototype这个仍是成立的,可是因为函数f在调用完Object.create方法以后就被销毁了,因此只有func.__proto__ === Func。ip
ok,最后总结一下
1.对象有属性__proto__,指向该对象的构造函数的原型对象。
2.方法除了有属性__proto__,还有属性prototype,prototype指向该方法的原型对象。原型