有什么方法可以让下面的东西在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。但是有没有办法让对象字面量的属性值依赖于之前声明的其他属性呢?
当前回答
现在在ES6中,你可以创建惰性缓存属性。在第一次使用时,该属性只计算一次,成为一个正常的静态属性。结果:第二次跳过数学函数开销。
神奇之处在于getter。
const foo = {
a: 5,
b: 6,
get c() {
delete this.c;
return this.c = this.a + this.b
}
};
在箭头getter中,这将拾取周围的词法作用域。
foo // {a: 5, b: 6}
foo.c // 11
foo // {a: 5, b: 6 , c: 11}
其他回答
你可以这样做
var a, b
var foo = {
a: a = 5,
b: b = 6,
c: a + b
}
当我必须引用函数最初声明的对象时,该方法已被证明对我有用。以下是我如何使用它的一个最小示例:
function createMyObject() {
var count = 0, self
return {
a: self = {
log: function() {
console.log(count++)
return self
}
}
}
}
通过将self定义为包含print函数的对象,允许函数引用该对象。这意味着如果您需要将print函数传递到其他地方,则不必将其“绑定”到对象。
如果您愿意,可以使用下面所示的方法
function createMyObject() {
var count = 0
return {
a: {
log: function() {
console.log(count++)
return this
}
}
}
}
然后下面的代码将记录0,1,2,然后给出一个错误
var o = createMyObject()
var log = o.a.log
o.a.log().log() // this refers to the o.a object so the chaining works
log().log() // this refers to the window object so the chaining fails!
通过使用self方法,可以保证print总是返回相同的对象,而不管函数在什么环境中运行。当使用createMyObject()的self版本时,上面的代码将正常运行并记录0、1、2和3的日志。
我认为下面的代码对于可维护性来说是最好的,尽管它不是在对象文字语法中:
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
};
因为不需要在运行时甚至编译时计算这个和。
我唯一能告诉你的是getter
Var foo = { 5, b: 6, 获取c() { 返回。A + this.b; } } Console.log (foo.c) // 11
这是由ECMAScript第5版规范引入的一个语法扩展,大多数现代浏览器(包括IE9)都支持该语法。
只是为了思考-地点对象的属性的时间轴:
var foo = {
a: function(){return 5}(),
b: function(){return 6}(),
c: function(){return this.a + this.b}
}
console.log(foo.c())
上面也有更好的答案。这是我如何修改你质疑的示例代码。
更新:
var foo = {
get a(){return 5},
get b(){return 6},
get c(){return this.a + this.b}
}
// console.log(foo.c);
这里有一个简洁的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]);