更改使用文字初始化创建的对象的原型

时间:2012-11-05 15:34:35

标签: javascript

假设我想只使用object literals(不是构造函数)。我有一个像这样的对象:

var o = {
  name : "Jack"
}

如果我想创建另一个原型为o的对象,我使用以下语法:

var u = Object.create( o );
console.log( u.name );//prints Jack
u.name = "Jill";
console.log( u.name );//prints Jill

工作正常!没问题。但现在在运行时我想将u的原型更改为其他内容。如果使用如下构造函数创建u

function U () {}
U.prototype.name = "Jack";
var u = new U;
console.log( u.name );//prints Jack

OR

function U () {
  this.name = "Jack";
}
var u = new U;
console.log( u.name );//prints Jack

但是当使用构造函数时,我可以完全改变原型

function U () {}
//totally changed the prototype object to another object
U.prototype = {
  dad : "Adam"
}
var u = new U;
console.log( u.dad );//prints Adam

然后,我添加到U原型的任何内容都会自动添加到这些更改后创建的每个对象中。但是如何使用Object文字获得相同的效果呢?

请提供最简单的解决方案,其语法简洁明了。我只想知道手动是否可以这样做。我也不想使用非标准__proto__关键字。

我搜索过Stackoverflow,这并不是以下问题的重复:

因为我想以标准方式(如果可能)在创建后更改原型。像Object.setPrototype()这样的东西会很完美,但是这个功能不存在!有没有其他方法可以简单地设置使用对象文字初始化创建的对象的原型?

1 个答案:

答案 0 :(得分:6)

使用当前规范,一旦对象的原型被实例化,就不能更改对象的原型(例如,换出一个并交换另一个)。 (但请参见下文,事情可能正在发生变化。)您只能修改对象的原型。但这可能是你想要的,看看你的问题。

要清楚区别:

var p1 = {
    foo1: function() {
        console.log("foo1");
    }
};
var p2 = {
    foo2: function() {
        console.log("foo1");
    }
};

var o = Object.create(p1);
o.foo1(); // logs "foo1"
o.foo2(); // ReferenceError, there is no foo2
// You cannot now *change* o's prototype to p2.
// You can modify p1:
p1.bar1 = function() { console.log("bar1"); };
// ...and those modifications show up on any objects using p1
// as their prototype:
o.bar1(); // logs "bar1"
// ...but you can't swap p1 out entirely and replace it with p2.

回到你的问题:

  

如果你是用这样的构造函数创建的......那么我添加到U原型的任何内容都会自动添加到这些更改之后创建的每个对象中。但是如何使用Object文字获得相同的效果呢?

通过修改传递给Object.create的对象作为原型,如上所述。请注意,bar1添加p1如何使其o可用,即使o在添加之前已创建o。正如构造函数一样,原型关系持续存在,p1在创建时不会获得<|的快照,它会获得持久的链接。


ES.next看起来很可能有“set prototype operator”(__proto__),这样就可以做到这一点。但目前还没有标准机制。有些引擎实现了一个名为{{1}}的伪属性,它现在提供了这个功能,但它没有标准化。