有什么办法可以让类似下面的东西在 JavaScript 中工作吗?
var foo = {
a: 5,
b: 6,
c: this.a + this.b // Doesn't work
};
在当前形式中,此代码显然会引发引用错误,因为this
没有引用foo
. 但是,是有什么办法可以在对象文本的属性值依赖于其他属性声明更早?
有什么办法可以让类似下面的东西在 JavaScript 中工作吗?
var foo = {
a: 5,
b: 6,
c: this.a + this.b // Doesn't work
};
在当前形式中,此代码显然会引发引用错误,因为this
没有引用foo
. 但是,是有什么办法可以在对象文本的属性值依赖于其他属性声明更早?
好吧,我唯一能告诉你的是getter:
var foo = {
a: 5,
b: 6,
get c() {
return this.a + this.b;
}
}
console.log(foo.c) // 11
这是 ECMAScript 第 5 版规范引入的语法扩展,大多数现代浏览器(包括 IE9)都支持该语法。
你可以这样做:
var foo = {
a: 5,
b: 6,
init: function() {
this.c = this.a + this.b;
return this;
}
}.init();
这将是对象的某种一次性初始化。
请注意,您实际上是在分配init()
to的返回值foo
,因此您必须return this
。
缺少显而易见的简单答案,因此为了完整性:
但是,是有什么办法可以在对象文本的属性值依赖于其他属性声明更早?
不。这里的所有解决方案都将它推迟到创建对象之后(以各种方式),然后分配第三个属性。在最简单的方法是只是这样做:
var foo = {
a: 5,
b: 6
};
foo.c = foo.a + foo.b;
所有其他人只是做同样事情的更间接的方式。(Felix 的特别聪明,但需要创建和销毁一个临时函数,增加了复杂性;并且要么在对象上留下额外的属性,要么[如果你有delete
那个属性]影响对该对象后续属性访问的性能。)
如果您需要将其全部放在一个表达式中,则可以在没有临时属性的情况下执行此操作:
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);
简单地实例化一个匿名函数:
var foo = new function () {
this.a = 5;
this.b = 6;
this.c = this.a + this.b;
};
现在在 ES6 中你可以创建惰性缓存属性。首次使用时,该属性会评估一次以成为正常的静态属性。结果:第二次跳过数学函数开销。
魔法就在吸气剂中。
const foo = {
a: 5,
b: 6,
get c() {
delete this.c;
return this.c = this.a + this.b
}
};
在箭头 getter 中this
拾取周围的词法范围。
foo // {a: 5, b: 6}
foo.c // 11
foo // {a: 5, b: 6 , c: 11}