JavaScript 中只有对象,没有类。
实际上,JavaScript 才是真正应该被称为「面向对象」的语言,因为它是少有的可以不通过类,直接创建对象的语言。
函数的 prototype 属性
在 JavaScript 中,之所以会有「类」的错觉,是因为函数默认都会有一个名为 prototype
的公有并且不可枚举的属性,这个属性会指向另一个对象:
function Foo() {}
Foo.prototype; // {}
Foo.prototype
所指向的对象通常被称为 Foo 的原型。
我们来看下代码:
function Foo() {}
var a = new Foo();
Object.getPrototypeOf(a) === Foo.prototype; // true
调用 new Foo()
时会创建一个新对象 a
,其中的一步就是将新对象 a
内部的 [[Prototype]] 链接(关联)到 Foo.prototype
所指向的对象。
Object.create(..) 方法
生成一个关联到其它对象的新对象,可以使用 Object.create(..)
方法。看下面的例子:
var anotherObj = {
a: 2
};
// 创建一个关联到 anotherObj 的对象
var myObj = Object.create(anotherObj);
myObj.a; // 2
现在 myObj
对象的 [[Prototype]] 关联到了 anotherObj
。显然 myObj.a
并不存在,仅是尽管如此,属性访问仍然成功地(在 anotherObj
中)找到值 2。
如果在 anotherObj
也找不到 a
并且 anotherObj
[[Prototype]] 链不为空的话,就会继续查找下去……这个过程会持续到找到匹配的属性名为止,要不然一直查找到 [[Prototype]] 链顶端的 Object.prototype
对象,还找不到就返回 undefined
了。