你不知道的JS系列上( 49 ) - 函数的特殊属性 prototype
JS 中有一个奇怪的行为一直被无耻的滥用,那就是模仿类。这种行为利用了函数的一种特殊特性:所有的函数默认都会拥有一个名为 prototype 的公有并且不可枚举的属性
function Foo() { // ... } Foo.prototype; // {}
Foo.prototype 会指向一个对象,这个对象通常被称为 Foo 的原型,或者这样称呼更容易理解,“被称为 Foo 的原型的那个对象”。这个对象到底是什么?
最直接的解释就是,这个对象是在调用 new Foo() 时创建的,最后会被关联到这个 Foo.prototype 对象上。
function Foo() { // ... } var a = new Foo(); Object.getPrototypeOf(a) === Foo.prototype
调用 new Foo() 时会创建 a,发生构造函数调用时,会自动执行下面的操作
1、创建(或者说构造)一个全新的对象。
2、这个新对象会被执行 [[原型]] 连接。
3、这个新对象会绑定到函数调用的 this。
4、如果函数没有返回其他对象,那么 new 表达式中的函数调用会自动返回这个新对象
第二步就是给 a 一个内部的 [[Prototype]] 连接,关联到 Foo.prototype 指向的那个对象。
在 JS 中,并没有复制机制。不能创建一个类的多个实例,只能创建多个对象,它们的 [[Prototype]] 关联的是同一个对象。但是在默认情况下并不会进行复制,因此这些对象(a 和 Foo的原型)之间并不完全失去联系,它们是互相关联的。
绝大多数 JS 开发者不知道的秘密是,new Foo() 这个函数调用实际上并没有直接创建关联,这个关联只是一个意外的副作用。new Foo() 只是间接完成了我们的目标;一个关联到其他对象的新对象。