【问题标题】:Changing prototype of an object which was created with literal initialization更改使用文字初始化创建的对象的原型
【发布时间】:2012-10-25 11:28:24
【问题描述】:

假设我只想使用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

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

【问题讨论】:

    标签: javascript


    【解决方案1】:

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

    要明确区别:

    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__ 的伪属性,它现在提供了这个功能,但它不是标准化的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-27
      • 1970-01-01
      • 2015-02-28
      相关资源
      最近更新 更多