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

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

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


当前回答

这里有一个简洁的ES6方法:

Var foo = (o => ({ ……啊, C: o.a + o.b ({})) 5, b: 6 }); console.log (foo);

我用它来做这样的事情:

const常量= Object.freeze( (_ => ({ _, flag_data: { (_。a_flag]:“foo”, (_。b_flag]:“酒吧”, [_.c_flag]:“力量” } ({})) a_flag: 5 b_flag: 6, c_flag: 7, }) ); console.log (constants.flag_data [constants.b_flag]);

其他回答

如果你的对象被编写成一个返回对象的函数,并且你使用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);

这里有一个简洁的ES6方法:

Var foo = (o => ({ ……啊, C: o.a + o.b ({})) 5, b: 6 }); console.log (foo);

我用它来做这样的事情:

const常量= Object.freeze( (_ => ({ _, flag_data: { (_。a_flag]:“foo”, (_。b_flag]:“酒吧”, [_.c_flag]:“力量” } ({})) a_flag: 5 b_flag: 6, c_flag: 7, }) ); console.log (constants.flag_data [constants.b_flag]);

这一切的关键是SCOPE。

您需要将想要定义的属性的“父”(父对象)封装为它自己的实例化对象,然后可以使用关键字this引用同级属性

记住这一点非常非常重要,如果你没有先这么做就引用了这个,那么这个就会引用外部作用域。这将是窗口对象。

var x = 9   //this is really window.x
var bar = {
  x: 1,
  y: 2,
  foo: new function(){
    this.a = 5, //assign value
    this.b = 6,
    this.c = this.a + this.b;  // 11
  },
  z: this.x   // 9 (not 1 as you might expect, b/c *this* refers `window` object)
};

为了完成,在ES6中我们有类(在撰写本文时,只有最新的浏览器支持,但在Babel, TypeScript和其他编译器中可用)

class Foo {
  constructor(){
    this.a = 5;
    this.b = 6;
    this.c = this.a + this.b;
  }  
}

const foo = new Foo();

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

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

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

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);