[英]How can I set a constructor object value to be a function of other values?
我试图通过在对象构造函数内的其他两个属性上运行函数来生成对象属性。
当我运行以下代码时:
var ConstObj = function() {
this.compositionDict = {
"rock": 0.8,
"iron": 0.15,
"gold": 0.05
};
this.totalVolume = 10000;
this.compVolDict = Object.keys(this.compositionDict).reduce(function(prev, curr) {
prev[curr] = this.compositionDict[curr] * this.totalVol;
return prev;
}, {});
}
var tempObj = new ConstObj;
我收到以下错误:
Uncaught TypeError: Cannot read property 'rock' of undefined(…)
我认为这是行不通的,因为在运行函数时实际上并未定义对象属性-但是我不知道要执行的操作的良好解决方法。
我可以创建一个在创建对象后添加新属性的函数,但似乎这种事情应该起作用。
这是一个问题this
不是你的内部正确的值reduce
功能。 每当创建新的闭包(例如function() { ... }
,都会创建一个新的上下文。 为了使this
指向正确的上下文,您必须bind
函数,或者必须使用变量来引用原始上下文。
this.compVolDict = Object.keys(this.compositionDict).reduce(function(prev, curr) {
prev[curr] = this.compositionDict[curr] * this.totalVol;
return prev;
}.bind(this), {});
或者,您可以使用变量来记录要在函数内部使用的上下文。 这有点丑陋,但是您会在各种用户态脚本中看到这种情况。
var _this = this;
this.compVolDict = Object.keys(this.compositionDict).reduce(function(prev, curr) {
prev[curr] = _this.compositionDict[curr] * _this.totalVol;
return prev;
}, {});
最后,另一种解决方案是使用ES6箭头函数 。 显然,这是最优雅的解决方案。
this.compVolDict = Object.keys(this.compositionDict).reduce((prev, curr) => {
prev[curr] = this.compositionDict[curr] * this.totalVol;
return prev;
}, {});
如果无法使用ES6,则可以使用诸如babel.js之类的编译器 ,它将ES6转换为ES5。 这是开始利用ES6的新功能,但仍然能够在ES5环境中运行的好方法。
this.compositionDict
是undefined
在reduce
,因为你在不同的范围是。
( function(prev, curr) {
那个)
保存对ConstObj
函数范围的引用,然后使用该引用代替:
var ConstObj = function() {
var that = this; // Store the reference to `this`.
this.compositionDict = {
"rock": 0.8,
"iron": 0.15,
"gold": 0.05
};
this.totalVolume = 10000;
this.compVolDict = Object.keys(this.compositionDict).reduce(function(prev, curr) {
prev[curr] = that.compositionDict[curr] * that.totalVol;
return prev; // ^ use `that` instead of `this`
}, {});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.