4

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

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

或者

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()会很完美,但那个功能不存在!有没有其他方法可以简单地设置使用对象字面量初始化创建的对象的原型?

4

1 回答 1

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,如上所述。请注意添加bar1to如何p1使它在 上可用o,即使o它是在添加之前创建的。就像构造函数一样,原型关系是持久的,o它不会得到p1创建时的快照,它会得到一个持久的链接。


ES.next 看起来可能有“设置原型运算符”(<|),这将使它成为可能。但是目前还没有标准的机制。一些引擎实现了一个名为的伪属性__proto__,它现在提供此功能,但它不是标准化的。

于 2012-11-05T15:37:06.750 回答