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

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

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


当前回答

我唯一能告诉你的是getter

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

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

其他回答

如果你的对象被编写成一个返回对象的函数,并且你使用ES6对象属性“方法”,那么它是可能的:

const module = (state) => ({
  a: 1,
  oneThing() {
    state.b = state.b + this.a
  },
  anotherThing() {
    this.oneThing();
    state.c = state.b + this.a
  },
});

const store = {b: 10};
const root = module(store);

root.oneThing();
console.log(store);

root.anotherThing();
console.log(store);

console.log(root, Object.keys(root), root.prototype);

两种惰性解决方案

这里已经有了很好的答案,我不是这方面的专家,但我是懒惰方面的专家,以我的专家眼光来看,这些答案似乎不够懒惰。

第一个:从匿名函数返回对象

T.J. Crowder, Henry Wrightson和Rafael Rocha的回答略有不同:

Var foo = (() => { //粘贴原始对象 Const foo = { 5, b: 6, }; //使用它们的属性 foo.c = foo。A + foo.b; //做任何你想做的事情 //最后返回对象 返回foo; }) (); console.log (foo);

稍微有点好处的是,只需要原样粘贴您的原始对象,而不用担心参数等(恕我直言,包装器函数通过这种方式变得相当透明)。

第二:使用setTimeout

如果你不需要立即使用foo.c,这个方法可以工作:

Var foo = { 5, b: 6, c: setTimeout(() => foo.c = foo.c。A + foo。b, 0) }; //首先,foo.c将是setTimeout返回的整数 console.log (foo); //但如果这不是一个问题,当时间进入事件循环时,值将被更新 setTimeout(() => console.log(foo), 0);

var x = {
    a: (window.secreta = 5),
    b: (window.secretb = 6),
    c: window.secreta + window.secretb
};

这与@slicedtoad的答案几乎相同,但没有使用函数。

在对象字面量上创建新函数并调用构造函数似乎与原始问题完全不同,而且没有必要。

在对象文字初始化期间不能引用兄弟属性。

var x = { a: 1, b: 2, c: a + b } // not defined 
var y = { a: 1, b: 2, c: y.a + y.b } // not defined 

计算属性的最简单的解决方案如下(没有堆,没有函数,没有构造函数):

var x = { a: 1, b: 2 };

x.c = x.a + x.b; // apply computed property

有几种方法可以做到这一点;这是我要用的:

function Obj() {
 this.a = 5;
 this.b = this.a + 1;
 // return this; // commented out because this happens automatically
}

var o = new Obj();
o.b; // === 6