要回答您的“开始...”,您可能仍然会遇到 Javascript 环境,其中
console.log(typeof Object.create);
将报告
undefined
或类似的(假设您甚至有一个带有可用日志功能的控制台对象。)该外部if (typeof Object.create !== 'function')
包装器的原因是仅在您的 JS 环境尚未这样做的情况下定义它。有许多旧浏览器和其他环境可能有一天会运行您的代码,而这些环境可能没有Object.create
定义。
现在至于这个实际函数是如何工作的,它基于 JS 如何处理对象。对象只是命名属性的集合,或者更恰当地说是字符串名称和属性值之间的关联。但许多人也有一个特殊的属性,那就是他们的prototype
. 这只是一个指向另一个对象的指针。该对象也可以有自己的prototype
对象,依此类推。prototype
但是,最终,当这些对象之一为空时,原型链就会消失。这些原型对象也是命名属性的集合,当 Javascript 引擎在你的对象中搜索命名属性时,如果它没有直接在你的对象上找到它,它会检查你的对象的原型是否可能包含它,如果不是,如果该对象的原型可能包含它,依此类推,直到链消失。
这些原型对象的意义在于它们可以共享。几个对象,甚至几百万个对象,可以共享一个原型。这与基于类的继承方案的工作方式大不相同,但通常可以用于类似的目的。您可以定义一个函数的单个副本,并且从公共构造函数创建的所有对象都将使用该副本。在创建此类技术之前Object.create
,这是在 Javascript 中进行面向对象编程的唯一真正方法。
Crockford 的代码正在使用旧技术来模拟新技术应该做的部分工作。 Object.create
定义了一些通过旧机制无法真正实现的行为,但最基本的行为只是简单地创建一个原型为指定对象的新对象。这正是使用旧技术所F.prototype = o; return new F();
完成的。因此,这段代码几乎是将新行为填充到旧环境中的标准方法。有关这方面的另一个示例,请参阅MDN 创建页面