【问题标题】:Understanding Crockford's Object.create shim了解 Crockford 的 Object.create shim
【发布时间】:2012-04-25 19:59:06
【问题描述】:

我一直在阅读有关 Crockford 垫片以防止覆盖原型的信息,并了解它有时不是最终的解决方案。我也明白ES5 Shim 可能是一个可行的替代方案。我还阅读了this post which provides a more robust, secure alternative。

不过,我还是想知道他的Object.create shim 在“说”什么,然后“在做什么”。谁能告诉我我的解释是否正确?

if (typeof Object.create === 'undefined') { 
//If the browser doesn't support Object.create

  Object.create = function (o) {
  //Object.create equals an anonymous function that accepts one parameter, 'o'.

    function F() {};
    //Create a new function called 'F' which is just an empty object.

    F.prototype = o;
    //the prototype of the 'F' function should point to the
    //parameter of the anonymous function.

    return new F();
    //create a new constructor function based off of the 'F' function.
  };
}

//Then, based off of the 'Lost' example in the Crockford book...

var another_stooge = Object.create(stooge);

//'another_stooge' prototypes off of 'stooge' using new school Object.create.
//But if the browser doesn't support Object.create,
//'another_stooge' prototypes off of 'stooge' using the old school method.

这样,当我们将东西扩充到“another_stooge”时,“stooge”对象的原型就不会被覆盖。无需使用 'constructor' 重置 'stooge' 原型。

提前致谢,

-k

【问题讨论】:

    标签: javascript prototype object-create


    【解决方案1】:
    if (typeof Object.create !== 'function') {
        Object.create = function (o) {
            function F() {}
            F.prototype = o;
            return new F();
        };
    }
    var oldObject={prop:'Property_one' }; // An object
    var newObject = Object.create(oldObject); // Another object
    

    在上面的示例中,我们使用create 方法创建了一个新对象newObject,它是Object 对象的成员函数,我们在(Crockford 的)示例中早先添加到Object 对象中.所以基本上它的作用是,create 方法声明了一个函数F,一个空对象every function is a first class object in javascript,然后我们继承了o 的原型(在这种情况下o 也是一个对象@ 987654331@ 作为 create 方法的参数传递)最后我们使用return new F(); 将新对象(F 的一个实例)返回到变量newObject,所以现在newObject 是一个继承oldObject 的对象.现在如果你写console.log(newObject.prop);,那么它将输出Property_one,因为我们的newObject 对象继承了oldObject,这就是为什么我们将prop 的值设为Property_one。这称为原型继承。

    你必须传递一个对象作为create方法的参数

    【讨论】:

      【解决方案2】:

      它所做的只是创建一个新的对象构造函数,即 F,然后将传递的对象分配给构造函数的原型属性,以便使用 F 构造函数创建的新对象继承这些方法。

      然后它使用构造函数返回一个新初始化的对象(new F() => F.prototype)

      但是 crockford 未能正确地重新分配构造函数,因为通常新的对象构造函数应该与其继承的对象构造函数相同。

      【讨论】:

      • 嗨,吉列斯克。感谢您的回复!那么在使用这个的时候,是不是意味着构造函数的原型需要重新设置呢?像:stooge.prototype.constructor = stooge;再次感谢!
      【解决方案3】:

      在你的 cmets 上:

      >   //Object.create equals an anonymous function that accepts one parameter, 'o'.
      

      最好将一个函数分配给Object 的create 属性。所有函数都可以被认为是匿名的,只是一些被分配给命名的属性或变量,而另一些则不是。

      > //Create a new function called 'F' which is just an empty object.
      

      声明一个函数。是的,它也是一个对象。

      >     F.prototype = o;
      >     //the prototype of the 'F' function should point to the
      >     //parameter of the anonymous function.
      

      将o 的引用分配给F.prototype 写起来有点短。

      >     //create a new constructor function based off of the 'F' function.
      

      不,应该是“返回 F 的实例”。所以返回的对象有一个内部的[[Prototype]],它引用了传递给函数的对象。混乱的部分是必须创建一个无用的 F 函数来执行该技巧,并且返回的对象的构造函数将没有有用的值,因为它引用了空的 F。

      并不是说构造函数属性通常非常可靠或特别有用。

      这样,'stooge'对象的原型不能被覆盖 当我们将东西添加到“another_stooge”时。无需重置 'stooge' 原型使用​​'constructor'。

      这是一个奇怪的说法。 *another_stooge* 拥有stooge,因为它是私有的[[Prototype]],它不是继承自stooge.prototype,而是继承自stooge.[[Prototype]]。

      如果你想让another_stooge继承stooge.prototype,使用Object.create(stooge.prototype)或Object.create(new stooge()),前者可能更合适。

      我希望一切都有意义。

      【讨论】:

      • 嗨,RobG。感谢您的回复!我必须重新阅读才能完全理解语法,但我肯定比一个小时前知道的更多。再次感谢!
      【解决方案4】:

      这里有两个技巧:

      1. F 不是一个简单的函数,它是一个构造函数。
      2. “F.prototype”只是一个属性,此时它与继承无关。 真正的诀窍是,当我们使用“new F()”时,“new”会创建一个新对象,调用构造函数(这里不做任何事情)并将新对象的内部“prototype”字段设置为“ F.prototype”,因此返回的对象将继承自“o”。

      所以我认为:

      • F 是构造函数
      • F 不是从 o 继承的
      • “new F”(即返回的对象)继承自o

      【讨论】:

        【解决方案5】:

        我猜想将内部函数命名为 Object 而不是 F 会使生成的对象看起来更接近 Object.create() 将创建的对象。

        if (typeof Object.create !== 'function') {
            Object.create = function (o) {
                function Object() {}
                Object.prototype = o;
                return new Object();
            };
        }
        

        【讨论】:

          猜你喜欢
          • 2015-10-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多