有什么方法可以让下面的东西在JavaScript中工作?
var foo = {
a: 5,
b: 6,
c: this.a + this.b // Doesn't work
};
在当前的表单中,这段代码显然抛出了一个引用错误,因为它没有引用foo。但是有没有办法让对象字面量的属性值依赖于之前声明的其他属性呢?
有什么方法可以让下面的东西在JavaScript中工作?
var foo = {
a: 5,
b: 6,
c: this.a + this.b // Doesn't work
};
在当前的表单中,这段代码显然抛出了一个引用错误,因为它没有引用foo。但是有没有办法让对象字面量的属性值依赖于之前声明的其他属性呢?
当前回答
你可以这样做:
var foo = {
a: 5,
b: 6,
init: function() {
this.c = this.a + this.b;
return this;
}
}.init();
这将是对象的某种一次性初始化。
请注意,您实际上是将init()的返回值分配给foo,因此必须返回this。
其他回答
有几种方法可以做到这一点;这是我要用的:
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 = {
a: 5,
b: 6,
init: function() {
this.c = this.a + this.b;
return this;
}
}.init();
这将是对象的某种一次性初始化。
请注意,您实际上是将init()的返回值分配给foo,因此必须返回this。
如果你想使用原生JS,其他答案提供了很好的解决方案。
但是如果你愿意写自引用对象,比如:
{
a: ...,
b: "${this.a + this.a}",
}
我写了一个叫做self- references -object的npm库,它支持这种语法并返回一个原生对象。
这里有一个简洁的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]);
两种惰性解决方案
这里已经有了很好的答案,我不是这方面的专家,但我是懒惰方面的专家,以我的专家眼光来看,这些答案似乎不够懒惰。
第一个:从匿名函数返回对象
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);