谈谈JavaScript的prototype

上一篇我们谈到了Object和Function的混乱关系,那么这一篇就来理一理。

在JavaScript中,所有对象都是由函数创建的,请看下面代码:

1
var obj = { key: "value"}

在如上代码中,obj 虽然是由字面量方式创建的,但它只是new Object()构建方式的语法糖,而Object是一个函数:typeof(object) // function。所以,对象是由函数创建的,下面我们一步步来解释。

每个函数function都有一个prototype属性,即原型。prototype本身是一个对象,有一个默认的属性constructor,属性值指向函数本身。而每个对象,都有一个隐式原型__proto__,值为创造该对象的function的prototype。为了证实这个理论,我们将用代码来验证一下:

1
2
3
4
5
6
7
> let obj = new Object()
> obj.__proto__ === Object.prototype
< true

> let obj2 = {}
> obj2.__proto__ === Object.prototype
< true

根据上面的代码,我们可以看出,不管是由哪种方式创建的对象,其__proto__都指向了Object的原型,所以,它们都是通过Object函数来创建的。

img

上面是一张大而全的关系图,我们试着捋一捋:首先,f1和f2是通过new Foo()的方式创建的,他们的__proto__指向了构造函数Foo.prototype,这个Foo.prototype也是一个对象,它的__proto__指向了Object.prototype,这说明了函数本身也是一个对象,而Object.prototype的__proto__的值为null,感觉像是到达了一个终点。

接着再捋一捋另一条路线,因为函数本身也是对象,所以函数也有自己的__proto__,如图,Object的__proto__指向了Function.prototype,说明Object是由Function创建的。而Function的__proto__指向了自己的prototype,这说明Function也是由Function创建的。

至此,大致理清了Object与Function的奇妙关系,所有对象都是由函数创建的,而函数本身,也是一种对象。