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

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

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


当前回答

如果你的对象被编写成一个返回对象的函数,并且你使用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中我们有类(在撰写本文时,只有最新的浏览器支持,但在Babel, TypeScript和其他编译器中可用)

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

const foo = new Foo();

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

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

这里发布的其他答案更好,但这里有一个替代答案:

在初始化时设置值(不是getter或派生的,等等) 不需要任何类型的init()或对象字面量之外的代码 是一个对象文字,而不是一个工厂函数或其他对象创建机制。 不应该有任何性能影响(初始化时除外)

自动执行匿名函数和窗口存储

var foo = {
    bar:(function(){
        window.temp = "qwert";
        return window.temp;
    })(),
    baz: window.temp
};

订单是有保证的(bar before baz)

它当然会污染window,但我无法想象有人会编写一个需要window的脚本。Temp是持久的。如果你偏执的话,可以试试tempMyApp。

它也很丑,但偶尔有用。一个例子是,当你使用一个具有严格初始化条件的API时,你不想重构,所以范围是正确的。

当然,它是干的。

可维护性很好的替代语法:

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

这是因为如果您没有显式地指定名称,JavaScript将使用变量名作为新创建的对象的属性名。对于像这样的短数组,如果在函数中,我个人会使用单行语法和return:

let a = 5;
let b = 6;
return { a, b, c:a+b };

我认为下面的代码对于可维护性来说是最好的,尽管它不是在对象文字语法中:

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

这将使用{}创建一个新的空对象,然后使用匿名函数设置其属性(使用call()执行)。我认为唯一不好的部分是需要返回这个,感觉像是多了一行代码。不幸的是,我不能想出任何更好的方法来移动引用新创建的匿名对象到foo。

我认为这比语法var foo = new function(){…}因为它不会在原型链中创建一个额外的级别,就像@Bergi在一个现有答案的评论中解释的那样。

然而,如果这是真正的字面意思,没有任何其他逻辑,只有一个添加,它将更有意义的只是写

const foo = {
    a:5,
    b:6,
    c:11, // sum of a + b
};

因为不需要在运行时甚至编译时计算这个和。