Crockford的对象创建技术发生了什么?

Chr*_*Noe 25 javascript creation object prototypal-inheritance

只有3行代码,但我很难完全掌握这个:

Object.create = function (o) {
    function F() {}
    F.prototype = o;
    return new F();
};
newObject = Object.create(oldObject);
Run Code Online (Sandbox Code Playgroud)

(来自Prototypal Inheritance)

  1. Object.create()通过创建一个名为的空函数开始F.我认为函数是一种对象.这个F对象存放在哪里?在全球范围内我猜.

  2. 接下来,我们oldObject传入o,成为功能的原型F.函数(即对象)F现在从我们"继承" oldObject,在名称解析将通过它的路上.很好,但我很好奇默认原型是什么对象,对象?这对于函数对象也是如此吗?

  3. 最后,F实例化并返回,成为我们的newObject.new这里的操作是否必要?还没有F提供我们需要的东西,或者功能对象和非功能对象之间是否存在重要区别?显然,使用这种技术不可能有一个构造函数.

下次Object.create()调用会发生什么?全局功能F被覆盖了吗?当然它不会被重用,因为这会改变以前配置的对象.如果多个线程调用会发生什么Object.create(),是否有任何类型的同步来防止竞争条件F

CMS*_*CMS 29

1)Object.create()从创建一个名为F的空函数开始.我认为函数是一种对象.这个F对象存放在哪里?在全球范围内我猜.

不,它存储在Object.create函数的本地范围内,每次调用Object.create此函数F都将被重新创建.

您甚至可以通过存储F在闭包上并重用它来创建更具内存效率的实现:

if (typeof Object.create !== "function") {
  Object.create = (function () {
    function F() {} // created only once
    return function (o) {
      F.prototype = o; // reused on each invocation
      return new F();
    };
  })();
}
Run Code Online (Sandbox Code Playgroud)

2)接下来,作为o传入的oldObject成为函数F的原型.函数(即对象)F现在从我们的oldObject"继承",在名称解析将通过它的路径中.很好,但我很好奇默认原型是什么对象,对象?这对于函数对象也是如此吗?

所有对象都有一个内部属性来构建原型链,这个属性被称为[[Prototype]],它是一个内部属性,虽然有些实现允许你使用属性访问它,比如mozilla obj.__proto__.

默认的[[Prototype]],当你创建一个新的对象,即var obj = {};Object.prototype.

所有函数都有一个prototype属性,当函数用作构造函数时,使用此属性,并使用new运算符调用.

它是在幕后创建的新对象实例,此对象[[Prototype]]设置为其构造函数的prototype属性.

3)最后,F被实例化并返回,成为我们的newObject.这里的"新"操作是否严格必要?F是否已经提供了我们需要的东西,或者功能对象和非功能对象之间是否存在重要区别?显然,使用这种技术不可能有一个构造函数.

是的,new操作员在这种方法中是必不可少的.

new运营商设置的唯一标准方式[[Prototype]]对象的内部属性,如果您想了解它是如何工作的,你可以给看看的[[Construct]]内部操作.

下次调用Object.create()时会发生什么?全局函数F是否被覆盖?当然它不会被重用,因为这会改变以前配置的对象.如果多个线程调用Object.create()会发生什么,是否有任何同步来防止F上的竞争条件?

下一次Object.create调用时,新的本地F函数仅在方法调用的范围内实例化,您不必担心竞争条件.

注意,此实现几乎一致的Object.create在描述的ECMAScript第5版规范,在该方法中,你可以通过一个属性描述符来初始化对象.

所有浏览器供应商都在实现它(已经在Firefox 3.7 alphas,最新的Wekit Nightly Builds和Chrome 5 Beta上提供),所以我建议你至少在覆盖它之前检查本机实现是否存在.


Tim*_*own 7

1)函数确实是一种对象.F每次Object.create调用时都会创建一个带有标识符的函数对象,并且只能在该执行期间使用该标识符访问该函数对象Object.create.因此,每次Object.create调用时,都会得到不同的函数对象F.此函数对象作为constructor返回的对象的属性而存在Object.create.

2)

F现在从我们的oldObject"继承",在名称解析将通过它的路上

这不是真的正确.将对象分配给函数someObjectprototype属性只意味着通过将此函数作为构造函数创建的任何未来对象的原型将是someObject.

3)new这项技术绝对至关重要.只有通过调用函数作为构造函数才能生成新对象,并且该对象的原型(通常不可访问)将设置为构造函数的prototype属性.没有其他(标准化)方法来设置对象的原型.

最后,浏览器中的JavaScript是单线程的,因此您描述的竞争条件是不可能的.

  • 竞争条件无论如何都不适用,因为`F`是`Object.create`函数的本地,而不是全局的. (3认同)