我一直在阅读Crockford垫片,以防止覆盖原型,并了解它有时不是最终/全部解决方案。我也明白ES5 Shim可能是一个可行的替代方案。我还阅读了this post which provides a more robust, secure alternative。
不过,我想知道他的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'对象的原型不能被覆盖。无需使用'构造函数'重置'stooge'原型。
提前致谢,
-k
答案 0 :(得分: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
在上面的示例中,我们使用newObject
方法创建了一个新对象create
,该方法是我们在Object
中添加的Object
对象的成员函数在我们(Crockford的)例子中早些时候的对象。基本上它是这样做的,create
方法声明了一个函数F
,一个空对象every function is a first class object in javascript
,然后我们继承了o
的原型(在这种情况下) o
也是作为create method参数传递的对象oldObject
,最后我们使用return new F();
将新对象(F的实例)返回给变量{{1} },所以现在newObject
是继承newObject
的对象。现在,如果您编写oldObject
,那么它会输出console.log(newObject.prop);
,因为我们的Property_one
对象已继承newObject
,这就是我们获得oldObject
值的原因为prop
。这被称为原型继承。
您必须将对象作为Property_one
方法
答案 1 :(得分:0)
它所做的只是创建一个新的对象构造函数,即F,然后将传递的对象分配给构造函数prototype属性,以便使用F构造函数创建的新对象继承这些方法。
然后使用构造函数返回一个新的初始化对象(new F()=> F.prototype)
但是crockford无法正确地重新分配构造函数,因为通常新对象构造函数应该与它继承的对象构造函数相同。
答案 2 :(得分:0)
关于你的意见:
> //Object.create equals an anonymous function that accepts one parameter, 'o'.
最好说一个函数已分配给create
的{{1}}属性。所有函数都可以被认为是匿名的,只是有些被分配给命名属性或变量,而其他函数则没有。
Object
声明一个函数。是的,它也是一个对象。
> //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
不,应该是“返回F的实例”。因此返回的对象有一个内部> //create a new constructor function based off of the 'F' function.
,它引用传递给函数的对象。混乱的部分是必须创建一个无用的F函数来执行该技巧,并且返回的对象的构造函数将没有有用的值,因为它引用空[[Prototype]]
。
无论如何,构造函数属性都不是非常可靠或特别有用。
这样,'stooge'对象的原型不能被覆盖 当我们将东西增加到'another_stooge'时。无需重置 'stooge'原型使用'构造函数'。
这是一个奇怪的陈述。 * another_stooge *有F
,因为它是私有的stooge
,它不会从[[Prototype]]
继承,而是从stooge.prototype
继承。
如果您希望stooge.[[Prototype]]
继承another_stooge
,请使用stooge.prototype
或Object.create(stooge.prototype)
,前者可能更合适。
我希望一切都有道理。
答案 3 :(得分:0)
这里有两个技巧:
所以我想,那:
答案 4 :(得分:-1)
我想将内部函数命名为Object
而不是F
会使得生成的对象看起来更接近于Object.create()
所创建的内容。
if (typeof Object.create !== 'function') {
Object.create = function (o) {
function Object() {}
Object.prototype = o;
return new Object();
};
}