有什么方法可以让下面的东西在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 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() {
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/
好吧,我想到了另一个解决方案。这里我想初始化一个对象,表示每个时间单位的毫秒数。 结果是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
}
这种方法的缺点是:
变量被定义为常量,即使我们不需要它们。因此它需要无用的内存。 对象的每个值必须声明为独立的变量
这里有一个简洁的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]);
我认为下面的代码对于可维护性来说是最好的,尽管它不是在对象文字语法中:
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
};
因为不需要在运行时甚至编译时计算这个和。
var x = {
a: (window.secreta = 5),
b: (window.secretb = 6),
c: window.secreta + window.secretb
};
这与@slicedtoad的答案几乎相同,但没有使用函数。