javascript中的Object.create:为什么我的代码输出Object而不是名称string值?

我testing了这个片段,并用node.js执行

function Person(name) { this.name = name; } john = Object.create(Person); john.name = 'John'; console.log(john.name); 

它返回Person。 为什么不返回“约翰”?

更新:我的问题不是关于新vs创build,我完全知道应该如何使用新build和创build。 我的问题是为什么我不能像往常一样设置名称属性值。

它返回Person 。 为什么不返回'John'

由于该Object.create行创build一个Person函数作为其原型的对象,并且Person函数对象有一个令人惊讶的name属性的定义,阻止您写入它。 (一旦你知道这个定义是有道理的,但起初它是令人惊讶的。)

当你做什么时你正在创造什么

 john = Object.create(Person); 

…是一个使用Person函数作为其基础原型的对象。 这不会创build一个Person 实例 (将使用Person.prototype作为其原型),它会创build一个实际使用函数对象Person本身作为原型的对象。

Person函数有一个叫做name的非可写属性,它是函数的名字(这个还没有在标准中,但是在ES6中[现在在草稿的9.2.2节中定义],而V8是它已经)。 由于该属性不可写john.name = 'John'不起任何作用。 (更多关于下面的不可写属性。)

如果你的目标是用Person.prototype创build一个新的对象作为对象的基础原型,你可以这样做:

 john = new Person(); 

要么

 john = Object.create(Person.prototype); 

既然Person接受一个论点,你可能会这么做

 john = new Person('John'); 

…而不是后来分配name


关于不可写属性的更多信息:如果还没有碰到它们,那么它们在第五版规范中被定义为后面的一部分。 这是一个例子:

 var parent = {}; Object.defineProperty(parent, "foo", { writable: false, value: "original" }); 

parent对象有一个不可写属性foo

 console.log(parent.foo); // "original" parent.foo = "bar"; console.log(parent.foo); // "original" 

如果我们使用parent作为原型,那么即使在子对象上我们也不能写foo

 var child = Object.create(parent); console.log(child.foo); // "original" child.foo = "bar"; console.log(child.foo); // "original" 

这就是你的代码中发生的事情。 parentPersonchildjohn

只是想了解一下:如果我们想在这个时候为孩子创build一个可写的属性,我们可以,但是不能通过赋值,我们必须使用defineProperty

 Object.defineProperty(child, "foo", { writable: true, value: child.foo // (just sets the initial value) }); console.log(child.foo); // "original" child.foo = "bar"; console.log(child.foo); // "bar" 

现在child自己的属性foo ,它隐藏(隐藏)其原型的foo ,并且是可写的。