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

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

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


当前回答

如果你想使用原生JS,其他答案提供了很好的解决方案。

但是如果你愿意写自引用对象,比如:

{ 
  a: ...,
  b: "${this.a + this.a}",
}

我写了一个叫做self- references -object的npm库,它支持这种语法并返回一个原生对象。

其他回答

为了完成,在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

某种终结应该能解决这个问题;

var foo = function() {
    var a = 5;
    var b = 6;
    var c = a + b;

    return {
        a: a,
        b: b,
        c: c
    }
}();

在foo中声明的所有变量对foo来说都是私有的,就像你在任何函数声明中所期望的那样,因为它们都在作用域中,所以它们都可以相互访问,而不需要引用this,就像你在函数中所期望的那样。不同之处在于这个函数返回一个对象,该对象公开私有变量并将该对象赋值给foo。最后,使用return{}语句返回希望作为对象公开的接口。

然后,函数在结束时使用()执行,这将导致整个foo对象被求值,其中的所有变量被实例化,返回对象被作为foo()的属性添加。

你可以这样做:

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

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

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

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

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

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