blog
blog copied to clipboard
_proto_和prototype的区别
_proto_和prototype的区别
作者:殷荣桧@腾讯
为什么会遇到这个问题呢,是因为我在用构造函数时发现用console.dir(constructor)其中有一个属性叫prototype,还有一个属性是__proto__,不仅是构造函数,普通函数也有(这个其实好理解,因为构造函数其实就是命名的时候函数名用了大写,本质上也是普通函数)。但是当查看对象的时候,发现其中只有一个\_\_proto\_\_的属性。如下图:那么问题就来了,这两者有什么区别呢,都是干什么用的呢。
先初步了解一下prototype和__proto__的区别.
- 只有函数才有prototype属性。
- __proto__是由prototype产生的。prototype是__proto__的父亲。
先来看一张图,再去深入的了解两者的差别:
从图中可以看出,所有的__proto__都是指向一个prototype.来看一个实例就知道原因了。
先写一个构造函数Foo,如上图所示的Foo:
function Foo(name){
this.name=name;
}
用这个构造函数来构造一些foo对象,
var foo=new Foo('foo');
这时Foo.prototype===foo.__proto__ //return true;正如图上所示。那么这个new了一下到底发生什么了呢,怎么就让foo.__proto__指向了了Foo.prototype呢。接下来就剖析一下new的过程中发生什么了。
function New(func){
var res={};
if(func.prototype!=null){
res.__proto__=func.prototype
}
var lastRes=func.apply(res,Array.prototype.slice.call(arguments,1));
if(typeof lastRes==="object"&&lastRes!== null){
return lastRes;
}
return res;
}
function Foo(name){
this.name=name;
}
var foo=New(Foo,"foo");
上面是自已实现了一下New这个方法,从内部结构可以看得很清楚,__proto__指向prototype的原因是因为res.__proto__=func.prototype这样一句话,两个指针指向是同一个地方。这样想信就好理解了。
总结:
只有函数才有prototype(ES规范规定的),其实想想也是,函数都可以当成构造函数使,用来构造出一个新的对象,所以它要有prototype属性来传递给它构造出来的对象的__proto__属性。对象要prototype也没用啊,它有不能用来构造然后传递,所以从道理上也能讲通为什么只有函数才有prototype。
参考资料:
https://stackoverflow.com/questions/1646698/what-is-the-new-keyword-in-javascript
看一下规范对 instanceof 操作符的描述,就很容易分清楚了。