prototype 、__proto__、constructor
如果你已经明白了构造函数,请往下看。对构造函数不理解的朋友请看第一篇
prototype 与 __proto__
首先我们来看一个代码:
function Person (name) {
this.name = name
}
var p1 = new Person('张三')
console.dir(p1) //显示对象所有属性
输出结果如下:
这就很奇怪,我创建对象时只添加name这个属性, __prototype__
这个属性是啥?为啥他还有一个Object的值?
先不着急这些问题,我们在原来的代码上再添加一句代码
function Person (name) {
this.name = name
}
var p1 = new Person('张三')
console.dir(p1)
console.dir(Person.prototype) //我是新添加的
打印结果如下:
我们发现p1.__proto__
与Person.prototype
惊人的相似,这俩有没有关系呢?
目前为止,我们发现如下几个问题:
__proto__
是啥?__proto__
的Object值是啥,与Person.prototype
有没有关系。
先看第二个问题,因为这个很好验证,用如下代码:
function Person (name) {
this.name = name
}
var p1 = new Person('张三')
console.log(p1.__proto__ === Person.prototype) //打印结果为true
看过上一篇文章应该明白,p1.__proto__
与Person.prototype
保存的地址变量是相同的。即p1.__proto__
与Person.prototype
指向同一块内存。
解决了这俩的关系后再看看这个__proto__是啥。 这个属性并不是留给代码使用的,而是给浏览器使用的。怎么验证呢, 在IE10及以下就打印console.log(p1.__proto__)
是undefined 而Person.prototype
则没有这个问题。
可以得出结论:p1.__proto__与Person.prototype 指向的是同一块内存。 __prototype__是浏览器使用的属性。如果要使用这个对象,得用Peroson.prototype。
prototype 中的constructor
construcor 翻译过来称为构造器。(所有翻译过来的的名称都是那么让人费解!),现在我们来看看constructor的长啥样:
//从上面的结论中我们明白p1.__proto__ 与 Person.prototype 是一样的
//我们就拿Person.prototype 来查看
function Person (name) {
this.name = name
}
console.log(Person.prototype)
打印如下:
可以看到Person.prototype
中有一个constructor
属性,并且它的值还没见过,那么这个值是什么呢?
其实这个值就是Person这个构造函数。我们来打印验证一下
function Person (name) {
this.name = name
}
console.dir (Person.prototype)
console.dir(Person)
打印如下:
可以看出Person.protootype.constructor
的值就是Person这个构造函数的地址(即constructor指向Person),这个可以自行验证如下:
console.log(Person.prototype.constructor === Person) //true
所以constructor
这个属性这个翻译成“来源地址”岂不是更开心。
看到这里,__proto__、prototype、constructor都理完了,总结一下:
1. __proto__
与 prototype
指向同一个内存 即 p1.__proto__ === Person.proto
2. __proto__
是给浏览器使用的属性,代码如果要使用最好使用 prototype
3. prototype
中的constructor指向的是Person
最后张图解释下:
1. function Person() {}
等价于 var Person = function () {}
, 所以这句话开辟了一个叫Person的内存空间。(并且这个时候prototype
也被创建出来了, 并且prototype.constructors
指向 Person
)
2. 通过new 关键字 创建出实例 p1
,p1.__proto__
指向 Person.prototype