我正在尝试创建一个简单的JavaScript计算器。但是,当我运行代码并对三个字段(值框或符号)中的任何一个进行更改时,我得到一个错误,说明
。计算不是函数
错误出现在this下面。根据是否更改数值或公式符号,计算正在调用的原型函数。
我已经阅读了闭包,回调和"this"关键字,我相信问题在于我如何调用我的原型函数。有人会帮助解释在我的代码我犯了一个错误,以及如何解决它?
这是JavaScript
var Formula=function() {
this.value1 = null;
this.value2 = null;
this.sign = null;
this.result = null;
};
Formula.prototype.calculate = function() {
switch (this.sign) {
case '+':
this.result = this.value1 + this.value2;
break;
case '-':
this.result = this.value1 - this.value2;
break;
case '/':
this.result = this.value1 / this.value2;
break;
case '*':
this.result = this.value1 * this.value2;
break;
default:
break;
}
document.querySelector('#result').innerHTML = this.result;
};
Formula.prototype.updateValue = function(event) {
if (event.currentTarget.id === '#value1')
this.value1 = parseFloat( event.currentTarget.value );
else this.value2 = parseFloat( event.currentTarget.value );
this.calculate();
};
Formula.prototype.updateSign = function(event) {
this.sign = event.currentTarget.value;
this.calculate();
};
document.addEventListener('DOMContentLoaded', function () {
(function() {
var equation = new Formula();
document.querySelector('#sign').addEventListener('change', equation.updateSign);
var values = document.querySelectorAll('.value');
for (var i = 0, numValues = values.length; i < numValues; i++) {
values[i].addEventListener('change', equation.updateValue);
}
})();
});
这里是HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="calcJS.js"></script>
</head>
<body>
<input type="number" class="value" id="value1"/>
<select id="sign">
<option value="+">+</option>
<option value="-">-</option>
<option value="*">*</option>
<option value="/">/</option>
</select>
<input type="number" class="value" id="value2"/>
=
<span id="result"/>
</body>
</html>
函数中的this
值取决于函数的调用方式。
通常当你做
var equation = new Formula();
equation.updateSign();
this
将是updateSign
然而,当你这样做的时候
var equation = new Formula();
document.querySelector('#sign').addEventListener('change', equation.updateSign);
您正在引用函数,而不是调用它,事件处理程序最终调用它,将this
值设置为更改的元素,而不是equation
对象
如果你想让this
成为对象,你必须做像
var equation = new Formula();
document.querySelector('#sign').addEventListener('change', function() {
equation.updateSign(arguments);
});
或使用bind返回一个具有this
集合值的新函数
var equation = new Formula();
document.querySelector('#sign').addEventListener('change', equation.updateSign.bind(equation));
小提琴
你还有一个逻辑缺陷
if (event.currentTarget.id === '#value1')
ID总是不带散列
返回if (event.currentTarget.id === 'value1')
您看到的问题是由于事件处理的工作方式。当调用事件处理程序时,作为事件目标元素的this
隐式传递给处理程序函数。
为了保持原来的this
作用域,您需要包装函数并直接调用它。例如:
var equation = new Formula();
document.querySelector('#sign').addEventListener('change', function(event)
{
equation.updateSign(event);
});
这提琴有助于说明。