2012-04-13 23 views
9

我一直在阅读克罗克福德垫片以防止重写原型,并了解它并不是最终所有/全部解决方案。我也明白ES5 Shim可能是一个可行的替代方案。我也读this post which provides a more robust, secure alternative了解克罗克福德的Object.create垫片

不过,我想知道他的Object.create垫片是“说”然后“做”。有人可以告诉我,如果我的解释评论是正确的吗?

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”原型。

由于提前,

-k

回答

14
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方法,这是我们在Object对象已经添加早些时候在我们(Crockford的)例子Object对象的成员函数创建一个新的对象newObject。所以基本上它所做的是,create方法声明一个函数F,一个空对象every function is a first class object in javascript然后我们继承了原型o(在这种情况下o也是一个对象oldObject作为create方法的参数传递),最后我们回到使用return new F();给变量newObject新对象(F的一个实例),所以现在newObject是继承了oldObject的对象。现在,如果你写console.log(newObject.prop);然后它会输出Property_one因为我们newObject对象继承了oldObject,这就是为什么我们已经得到的prop值作为Property_one。这被称为原型继承。

你必须通过一个对象作为create方法

+0

阿!我想我明白了。谢谢谢赫......您的帮助非常感谢! – kaidez 2012-04-13 14:20:45

+0

你是最好的:-) – 2012-04-13 14:25:35

0

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

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

但克罗克福德一个失败重新分配的构造正确地作为通常的新对象构造器应该是相同的作为它继承的对象构造函数。

+0

gillesc嗨。感谢您的回应!所以当使用这个时,这是否意味着构造函数的原型需要重置?例如: stooge.prototype.constructor = stooge; 再次感谢! – kaidez 2012-04-13 12:59:02

0

您的意见:

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

不如说是一个功能被分配到的Objectcreate财产。所有函数都可以被认为是匿名的,只是有些函数被分配给了命名的属性或变量,而另一些则不是。

> //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

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

这样,“跟屁虫”对象的原型不能覆盖 当我们加强东西“another_stooge”。无需使用'构造函数'重置 'stooge'原型。

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

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

我希望所有有意义。

+0

Hi RobG。感谢您的回应!我必须重读完全理解语法,但我当然知道的比我在一个小时以前做得更多。再次感谢! – kaidez 2012-04-13 14:20:09

0

的参数有两个技巧在这里:

  1. F不是一个简单的函数,它是一个构造函数。
  2. “F.prototype”只是一个属性,它什么都不做与传承在这一刻。 真正的窍门是,当我们用“新F()”,“新”创建一个新的对象,再调用构造函数(它不会做任何事情在这里),并设置新对象的内部的“原型”字段的值“F.prototype”,所以返回的对象将从“o”继承。

所以我觉得,认为:

  • F是一个构造
  • F不继承Ø
  • “新F”(这是返回的对象)是由邻
  • 继承
-1

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

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