您的问题的版本有一个错误Object.create:循环将属性附加到构造函数F(而不是返回的对象或其原型),这意味着它们在创建的对象中不可访问。
第二个参数 to 的属性Object.create应该被复制到新创建的对象中。MozillaObject.create的文档是这样写的:
如果指定且未定义,则其可枚举自身属性的对象(即,在其自身上定义的那些属性,而不是沿其原型链的可枚举属性)指定要添加到新创建的对象的属性描述符,以及相应的属性名称。
尝试使用问题中的版本运行以下代码Object.create:
o = Object.create(
{a: "prototype's a", b: "prototype's b"},
{a: "object's a"}
);
你会发现o.a == "prototype's a"and丢失了。o.b == "prototype's b""object's a"
该函数的以下版本可能会更有用:
Object.create = function(o, props) {
var newObj;
// Create a constructor function, using o as the prototype
function F() {}
F.prototype = o;
// Create a new object using F as the constructor function
newObj = new F();
// Attach the properties of props to the new object
if (typeof(props) === "object") {
for (prop in props) {
if (props.hasOwnProperty((prop))) {
newObj[prop] = props[prop];
}
}
}
return newObj;
};
让我们用同样的例子来试试:
o = Object.create(
{a: "prototype's a", b: "prototype's b"},
{a: "object's a"}
);
新对象o是使用具有属性和它自己的属性的原型a创建b的a。
我们o.b先来看:o.hasOwnProperty("b")会返回false,因为o没有一个属性叫b. 这就是原型的用武之地;因为没有属性b,所以在原型上查找它,因此o.b === "prototype's b".
另一方面,o.hasOwnProperty("a")将返回true,因为o确实有一个a属性。 o.a == "object's a"并且没有从原型中查找任何内容。
正如@chuckj 的回答所指出的,正确的实现Object.create比这更复杂。有关更多详细信息,请参阅John Resig 关于 ECMAScript 5 对象和属性的帖子。