未捕获的类型错误:函数不是函数
2019-01-14
6426
我得到
Fib.inputValidate 不是一个函数
我想要运行
inputValidate
方法,以便在
keyup
上输入既可以验证为
整数
,也可以验证为
斐波那契
数字:
HTML 如下所示:
<form id="fibonacci-form" action="" method="post">
<input id="fibonacci" type="text" name="fibonacci"/>
</form>
Javascript ES6:
class Fibonacci {
constructor() {
const isPerfectSquare = '';
const isFibonacci = '';
const isInt = '';
const inputValidate = '';
this.isPerfectSquare = isPerfectSquare;
this.isFibonacci = isFibonacci;
this.isInt = isInt;
this.inputValidate = inputValidate;
} // constructor
inputValidate(valueParsed, isInt) {
var field = document.getElementById('fibonacci');
var valueParsed = parseInt(field.value);
field.addEventListener("keyup", function(e) {
if (this.isInt(valueParsed) === false && field.value !== '') {
alert('Please enter a valid integer.');
}
if(this.isFibonacci(valueParsed)) {
alert(valueParsed + ' is a Fibonacci Number.');
} else {
alert(valueParsed + ' is not a Fibonacci Number.');
}
});
}
isInt(valueParsed) {
var field = document.getElementById('fibonacci');
var valueParsed = parseInt(field.value);
return !isNaN(valueParsed) && valueParsed == valueParsed.toFixed();
}
isPerfectSquare(valueParsed) {
var field = document.getElementById('fibonacci');
var valueParsed = parseInt(field.value);
var squaredValue = parseInt(Math.sqrt(valueParsed).toFixed(0));
if (field.value !== '') {
return (squaredValue * squaredValue == valueParsed);
}
}
isFibonacci(valueParsed) {
var field = document.getElementById('fibonacci');
var valueParsed = parseInt(field.value);
var squaredValue = parseInt(Math.sqrt(valueParsed).toFixed(0));
return this.isPerfectSquare(5 * valueParsed * valueParsed + 4) || this.isPerfectSquare(5 * valueParsed * valueParsed - 4);
}
} // class
let Fib = new Fibonacci();
console.log(Fib.inputValidate());
3个回答
真正的问题
是事件处理程序中的
this
与您想象的不一样。事件处理程序中的
this
将是触发事件的 (DOM) 元素,而不是类的实例。
现在,当您尝试修复真正的问题时,您最终遇到了
另一个问题
,即您正在使用具有空字符串
''
值的属性来隐藏类方法。
要解决此问题,只需将构造函数全部删除,因为它不执行任何操作,然后修复事件侦听器中的
this
问题。您可以通过多种方式实现此目的:
-
在事件侦听器范围之外使用一个变量,例如
that
,将this
分配给它,并在事件侦听器内部使用that
而不是this
。
如下所示:
var that = this;
field.addEventListener("keyup", function(e) {
// use 'that' instead of 'this'
if(that.isInt(valueParsed) ...
});
-
使用箭头函数,因为箭头函数使用其周围的
this
值:
如下所示:
// notice the arrow function passed to addEventListener
field.addEventListener("keyup", e => {
// you can now use 'this' here with no problems
if(this.isInt(valueParsed) ...
});
-
将您的事件处理程序绑定
到您的类的实例。bind
函数将创建一个新函数,该函数的this
值始终设置为您设置的值。
如下所示:
field.addEventListener("keyup", function(e) {
// you can now use 'this' here with no problems
if(this.isInt(valueParsed) ...
}.bind(this)); // bind the function to its surronding 'this' value so 'this' inside it will be the same as 'this' outside it
工作代码: 使用箭头函数
class Fibonacci {
inputValidate(valueParsed, isInt) {
var field = document.getElementById('fibonacci');
var valueParsed = parseInt(field.value);
field.addEventListener("keyup", e => {
if (this.isInt(valueParsed) === false && field.value !== '') {
alert('Please enter a valid integer.');
}
if (this.isFibonacci(valueParsed)) {
alert(valueParsed + ' is a Fibonacci Number.');
} else {
alert(valueParsed + ' is not a Fibonacci Number.');
}
});
}
isInt(valueParsed) {
var field = document.getElementById('fibonacci');
var valueParsed = parseInt(field.value);
return !isNaN(valueParsed) && valueParsed == valueParsed.toFixed();
}
isPerfectSquare(valueParsed) {
var field = document.getElementById('fibonacci');
var valueParsed = parseInt(field.value);
var squaredValue = parseInt(Math.sqrt(valueParsed).toFixed(0));
if (field.value !== '') {
return (squaredValue * squaredValue == valueParsed);
}
}
isFibonacci(valueParsed) {
var field = document.getElementById('fibonacci');
var valueParsed = parseInt(field.value);
var squaredValue = parseInt(Math.sqrt(valueParsed).toFixed(0));
return this.isPerfectSquare(5 * valueParsed * valueParsed + 4) || this.isPerfectSquare(5 * valueParsed * valueParsed - 4);
}
} // class
let Fib = new Fibonacci();
<form id="fibonacci-form" action="" method="post">
<input id="fibonacci" type="text" name="fibonacci" />
</form>
增强的工作代码:
您的代码中仍然存在一些与功能而非错误相关的问题:
-
您将函数声明为具有参数,但您并未使用它们。例如,
valueParsed
参数根本没有使用,尽管它是所有函数中的参数,而是您每次都从 DOM 元素中获取它。使用参数。 -
valueParsed
(现在用作参数)将在inputValidate
内初始化。它应该从事件侦听器内部获取,而不是从外部获取(每次触发事件时,我们都应该为valueParsed
获取一个新值)。 -
对于验证,如果您想排除浮点数,请使用
Number
而不是parseInt
(使用parseInt
将让浮点数通过验证,因为它只取整数位)。此外,如果验证失败,请使用return
停止进一步执行代码。但它(验证)仍然不是很好,我会把它留给你。 -
建议:
您可能希望使用一个按钮并监听按钮上的点击,而不是监听字段上的
keydown
输入,这很烦人。创建一个按钮,当用户单击按钮时,检查他们在字段中输入的数字是否是斐波那契数。您只需更改一两行代码即可实现此目的。
class Fibonacci {
inputValidate() {
var field = document.getElementById('fibonacci');
field.addEventListener("keyup", e => {
var valueParsed = Number(field.value);
if (this.isInt(valueParsed) === false) {
alert('Please enter a valid integer.');
return;
}
if (this.isFibonacci(valueParsed)) {
alert(valueParsed + ' is a Fibonacci Number.');
} else {
alert(valueParsed + ' is not a Fibonacci Number.');
}
});
}
isInt(valueParsed) {
return !isNaN(valueParsed) && valueParsed == valueParsed.toFixed();
}
isPerfectSquare(valueParsed) {
var squaredValue = parseInt(Math.sqrt(valueParsed).toFixed(0));
return (squaredValue * squaredValue == valueParsed);
}
isFibonacci(valueParsed) {
var squaredValue = parseInt(Math.sqrt(valueParsed).toFixed(0));
return this.isPerfectSquare(5 * valueParsed * valueParsed + 4) || this.isPerfectSquare(5 * valueParsed * valueParsed - 4);
}
} // class
let Fib = new Fibonacci();
<form id="fibonacci-form" action="" method="post">
<input id="fibonacci" type="text" name="fibonacci" />
</form>
ibrahim mahrir
2019-01-15
删除(或清空)您的构造函数。类方法会自动被类的实例继承,而您的构造函数只是用值为空字符串的属性覆盖它们。
Hydrothermal
2019-01-14
从构造函数中删除
this.inputValidate
和
const inputValidate
。然后按如下方式编写方法...
inputValidate = (valueParsed, isInt) => {
// do stuff here
};
Pablo Darde
2019-01-14