我得到Fib.inputValidate is not a function
我想运行inputValidate
方法,以使在keyup
上的输入既可以验证为integer
,也可以验证为Fibonacci
数字:
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());
答案 0 :(得分:2)
真正的问题是事件处理程序中的this
并不是您想的那样。事件处理程序中的this
将是引发事件的(DOM)元素,而不是类的实例。
现在,当您尝试解决实际问题时,最终遇到了另一个问题,这是因为您用属性值为空字符串{{1} }。
要解决此问题,只需将构造函数全部删除即可,因为它不会执行任何操作,并使用事件侦听器中的''
解决此问题。为此,您有很多方法:
this
,为其分配that
,并在事件侦听器内部使用this
代替that
。 / li>
像这样:
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
调用一个函数将创建一个新函数,该函数始终将其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>
参数根本没有使用,即使它在所有函数中都是参数,而是每次都从DOM元素中获取它。使用参数。valueParsed
(现在用作参数)将在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();
答案 1 :(得分:0)
删除(或清空)您的构造函数。类方法是由类的实例自动继承的,并且因为它是构造函数,因此只需将其值为空字符串的属性覆盖它们即可。
答案 2 :(得分:0)
从构造函数中删除this.inputValidate
和const inputValidate
。然后用这种方式编写您的方法...
inputValidate = (valueParsed, isInt) => {
// do stuff here
};
答案 3 :(得分:0)
您的构造函数将覆盖类中的每个函数。这是每种方法实际发生的情况(我以isInt()
为例,但每种方法完全相同):
您在构造函数中将isInt
设置为''
(空字符串):
const isInt = '';
然后,创建一个名为isInt
的属性,并将其设置为isInt
字符串:
this.isInt = isInt;
所以isInt
最终是一个空字符串。这是一个缩小的示例:
class Fibonacci {
constructor() {
const isInt = '';
this.isInt = isInt;
} // constructor
isInt(valueParsed) {
var field = document.getElementById('fibonacci');
var valueParsed = parseInt(field.value);
return !isNaN(valueParsed) && valueParsed == valueParsed.toFixed();
}
} // class
let Fib = new Fibonacci();
console.log(Fib);
如您所见,属性isInt
等于""
(空字符串),这就是为什么不能像函数一样调用它的原因-它是一个字符串。
将函数声明放在构造函数中:
class Fibonacci {
constructor() {
this.inputValidate = function(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.');
}
});
}
this.isInt = function(valueParsed) {
var field = document.getElementById('fibonacci');
var valueParsed = parseInt(field.value);
return !isNaN(valueParsed) && valueParsed == valueParsed.toFixed();
}
this.isPerfectSquare = function(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);
}
}
this.isFibonacci = function(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);
答案 4 :(得分:0)
在您的代码下面的行中引发的问题。
const inputValidate ='';
this.inputValidate = inputValidate;
这是什么意思,它意味着将const变量 inputValidate 分配给了 this.inputValidate ,所以 this.inputValidate 不是函数。
与之相反, inputValidate(valueParsed,isInt)本质上已添加到为该类创建的对象的原型中。
所以,当您在下面的行中调用
let Fib = new Fibonacci();
console.log(Fib.inputValidate());
然后先在类/构造函数中找到 Fib.inputValidate ,如果找不到,请在原型中找到 Fib.inputValidate 。
因此,当您调用 Fib.inputValidate()时,它会在其构造函数中找到该函数,但是它发现 Fib.inputValidate 是一个类似于变量的属性,但不是功能。
这就是为什么显示未捕获的TypeError:函数不是函数
有关概念,您可以阅读enter link description here
实际上javascript中没有类,但是ES6引入了一个class关键字,实际上这个class关键字只是语法糖。
所以每个人都应该记住课堂的实际情况。
最后对您的代码进行一些修改:
constructor() {
const isPerfectSquare = '';
const isFibonacci = '';
const isInt = '';
const inputValidate = '';
} // constructor
现在Fib.inputValidate()将可以访问。
最后进入按键/键或任何其他事件,此总是指向Dom元素,因此,如果您将箭头功能用于按键/键或任何其他事件,则< strong>这将指向类对象。