有什么方法可以让下面的东西在JavaScript中工作?

var foo = {
    a: 5,
    b: 6,
    c: this.a + this.b  // Doesn't work
};

在当前的表单中,这段代码显然抛出了一个引用错误,因为它没有引用foo。但是有没有办法让对象字面量的属性值依赖于之前声明的其他属性呢?


当前回答

你可以这样做:

var foo = {
   a: 5,
   b: 6,
   init: function() {
       this.c = this.a + this.b;
       return this;
   }
}.init();

这将是对象的某种一次性初始化。

请注意,您实际上是将init()的返回值分配给foo,因此必须返回this。

其他回答

只是为了思考-地点对象的属性的时间轴:

var foo = {
    a: function(){return 5}(),
    b: function(){return 6}(),
    c: function(){return this.a + this.b}
}

console.log(foo.c())

上面也有更好的答案。这是我如何修改你质疑的示例代码。

更新:

var foo = {
    get a(){return 5},
    get b(){return 6},
    get c(){return this.a + this.b}
}
// console.log(foo.c);

我唯一能告诉你的是getter

Var foo = { 5, b: 6, 获取c() { 返回。A + this.b; } } Console.log (foo.c) // 11

这是由ECMAScript第5版规范引入的一个语法扩展,大多数现代浏览器(包括IE9)都支持该语法。

get属性工作得很好,你也可以对只运行一次的“昂贵”函数使用绑定闭包(这只适用于var,而不适用于const或let)

var info = { address: (function() { return databaseLookup(this.id) }).bind(info)(), get fullName() { console.log('computing fullName...') return `${this.first} ${this.last}` }, id: '555-22-9999', first: 'First', last: 'Last', } function databaseLookup() { console.log('fetching address from remote server (runs once)...') return Promise.resolve(`22 Main St, City, Country`) } // test (async () => { console.log(info.fullName) console.log(info.fullName) console.log(await info.address) console.log(await info.address) console.log(await info.address) console.log(await info.address) })()

显而易见,简单的答案是缺失的,所以为了完整:

但是有没有办法让对象字面量的属性值依赖于之前声明的其他属性呢?

不。这里的所有解决方案都将它延迟到对象创建之后(以各种方式),然后分配第三个属性。最简单的方法就是这样做:

var foo = {
    a: 5,
    b: 6
};
foo.c = foo.a + foo.b;

其他的都是做同样事情的更间接的方式。(Felix的方法特别聪明,但需要创建和销毁临时函数,这增加了复杂性;并且要么在对象上留下额外的属性,要么[如果删除该属性]影响该对象上后续属性访问的性能。)

如果你需要它都在一个表达式中,你可以不使用temporary属性:

var foo = function(o) {
    o.c = o.a + o.b;
    return o;
}({a: 5, b: 6});

当然,如果你需要多次这样做:

function buildFoo(a, b) {
    var o = {a: a, b: b};
    o.c = o.a + o.b;
    return o;
}

然后你需要使用它的地方:

var foo = buildFoo(5, 6);

您可以使用模块模式来实现这一点。就像:

var foo = function() {
  var that = {};

  that.a = 7;
  that.b = 6;

  that.c = function() {
    return that.a + that.b;
  }

  return that;
};
var fooObject = foo();
fooObject.c(); //13

使用这个模式,你可以根据需要实例化几个foo对象。

http://jsfiddle.net/jPNxY/1/