有什么方法可以让下面的东西在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对象属性“方法”,那么它是可能的:
const module = (state) => ({
a: 1,
oneThing() {
state.b = state.b + this.a
},
anotherThing() {
this.oneThing();
state.c = state.b + this.a
},
});
const store = {b: 10};
const root = module(store);
root.oneThing();
console.log(store);
root.anotherThing();
console.log(store);
console.log(root, Object.keys(root), root.prototype);
其他回答
我认为下面的代码对于可维护性来说是最好的,尽管它不是在对象文字语法中:
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
};
因为不需要在运行时甚至编译时计算这个和。
有几种方法可以做到这一点;这是我要用的:
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 x = {
a: (window.secreta = 5),
b: (window.secretb = 6),
c: window.secreta + window.secretb
};
这与@slicedtoad的答案几乎相同,但没有使用函数。
您可以使用模块模式来实现这一点。就像:
var foo = function() {
var that = {};
that.a = 7;
that.b = 6;
that.c = function() {
return that.a + that.b;
}
return that;
};
var fooObject = foo();
fooObject.c(); //13
使用这个模式,你可以根据需要实例化几个foo对象。
http://jsfiddle.net/jPNxY/1/
如果你的对象被编写成一个返回对象的函数,并且你使用ES6对象属性“方法”,那么它是可能的:
const module = (state) => ({
a: 1,
oneThing() {
state.b = state.b + this.a
},
anotherThing() {
this.oneThing();
state.c = state.b + this.a
},
});
const store = {b: 10};
const root = module(store);
root.oneThing();
console.log(store);
root.anotherThing();
console.log(store);
console.log(root, Object.keys(root), root.prototype);