您的问题的版本有一个错误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 对象和属性的帖子。