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

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

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


当前回答

好吧,我想到了另一个解决方案。这里我想初始化一个对象,表示每个时间单位的毫秒数。 结果是typescript中的enum在我的例子中不能使用,所以我声明了多个变量,并将其分配给一个对象,如下所示:

const SECOND = 1000
const MINUTE = 60 * SECOND
const HOUR = 60 * MINUTE
const DAY = 24 * HOUR
const WEEK = 7 * DAY

export const TimeInMS = {
  SECOND,
  MINUTE,
  HOUR,
  DAY,
  WEEK
}

这种方法的缺点是:

变量被定义为常量,即使我们不需要它们。因此它需要无用的内存。 对象的每个值必须声明为独立的变量

其他回答

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

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

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

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

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

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

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

当然,它是干的。

简单地实例化一个匿名函数:

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

下面是对象中'this'行为的一个例子。

this.prop = 'external';
global.prop = 'global.prop';
const that = this;

const a = {
  prop: 'internal',
  prop1: this.prop, //external

  log() {
    return this.prop //internal
  },
  log1: () => {
    return this.prop //external
  },
  log2: () => {
    return function () {
      return this.prop; //'global.prop' in node; 'external' in chrome
    }()
  },
  log3: function () {
    return (() => {
      return this.prop; //internal
    })()
  },
}

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

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

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

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

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

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

const foo = new Foo();