扩展 Number 对象时出现语法错误
SyntaxError when extending Number object
我正在尝试使用以下代码扩展 Number
对象:
Number.prototype.isNumber = function(i){
if(arguments.length === 1){
return !isNaN(parseFloat(i)) && isFinite(i);
} else {
return !isNaN(parseFloat(this)) && isFinite(this);
}
}
try {
var x = 8.isNumber();
} catch(err) {
console.log(err);
}
我得到SyntaxError: identifier starts immediately after numeric literal
还有当我尝试以下操作时:
Number.isNumber(8)
我明白了 Number.isNumber is not a function
!!
JavaScript 解析器将 8.isNumber
读取为数字文字。
要在数字文字上访问 Number
方法,您必须用括号将数字括起来,以便 JavaScript 解释器知道您正在尝试使用数字属性。
Number.prototype.isNumber = function(i) {
if (arguments.length === 1) {
return !isNaN(parseFloat(i)) && isFinite(i);
}
return !isNaN(parseFloat(this)) && isFinite(this);
}
try {
var x = (8).isNumber();
console.log(x);
} catch(err) {
console.log(err);
}
尽管您已经接受了一个答案,但我还是忍不住提供了一个额外的答案。
您需要知道的第一件事是,Number
对象与 Number
原型 (see here) 之间存在根本区别。
就目前而言,您正在扩展 Number
原型,而不是对象本身!您的 isNumber
实施实际上具有与以下相同的效果:
Number.prototype.isNumber = function(){return isFinite(this)}
为什么?因为为了执行这个原型方法,解析器首先需要知道你调用函数的文字类型。这就是为什么您需要通过将数字字面量括在括号中来将其转换为表达式:(8).isNumber()
或使用更奇怪的符号 8..isNumber()
(第一个 .
是小数点,第二个 属性 访问器)。此时,javascript 引擎已经将其评估为 Number
,因此可以执行 isNumber()
方法。
另一方面,尽管乍一看您的代码看起来可以正确处理以下情况(因为您正在执行 parseFloat):"8".isNumber()
将始终抛出异常,因为这里我们有一个字符串文字,并且 String
原型没有相应的方法。这意味着,您将永远无法首先检测到实际上是字符串文字的数字。
您应该做的是直接扩展 Number
对象,这样您实际上就可以进行适当的检查而不必处理错误:
Number.isFiniteNumber = function(i){
return !Number.isNaN(i) && Number.isFinite(i);
}
Number.isFiniteNumber(8); // returns true
Number.isFiniteNumber("3.141"); // returns true
Number.isFiniteNumber(".2e-34"); // returns true
Number.isFiniteNumber(Infinity); // returns false
// just for informational purposes
typeof Infinity === "number" // is true
奖金 material:
Extending native objects is potentially dangerous.
Number.isNaN()
probably does not what you think it does.
我正在尝试使用以下代码扩展 Number
对象:
Number.prototype.isNumber = function(i){
if(arguments.length === 1){
return !isNaN(parseFloat(i)) && isFinite(i);
} else {
return !isNaN(parseFloat(this)) && isFinite(this);
}
}
try {
var x = 8.isNumber();
} catch(err) {
console.log(err);
}
我得到SyntaxError: identifier starts immediately after numeric literal
还有当我尝试以下操作时:
Number.isNumber(8)
我明白了 Number.isNumber is not a function
!!
JavaScript 解析器将 8.isNumber
读取为数字文字。
要在数字文字上访问 Number
方法,您必须用括号将数字括起来,以便 JavaScript 解释器知道您正在尝试使用数字属性。
Number.prototype.isNumber = function(i) {
if (arguments.length === 1) {
return !isNaN(parseFloat(i)) && isFinite(i);
}
return !isNaN(parseFloat(this)) && isFinite(this);
}
try {
var x = (8).isNumber();
console.log(x);
} catch(err) {
console.log(err);
}
尽管您已经接受了一个答案,但我还是忍不住提供了一个额外的答案。
您需要知道的第一件事是,Number
对象与 Number
原型 (see here) 之间存在根本区别。
就目前而言,您正在扩展 Number
原型,而不是对象本身!您的 isNumber
实施实际上具有与以下相同的效果:
Number.prototype.isNumber = function(){return isFinite(this)}
为什么?因为为了执行这个原型方法,解析器首先需要知道你调用函数的文字类型。这就是为什么您需要通过将数字字面量括在括号中来将其转换为表达式:(8).isNumber()
或使用更奇怪的符号 8..isNumber()
(第一个 .
是小数点,第二个 属性 访问器)。此时,javascript 引擎已经将其评估为 Number
,因此可以执行 isNumber()
方法。
另一方面,尽管乍一看您的代码看起来可以正确处理以下情况(因为您正在执行 parseFloat):"8".isNumber()
将始终抛出异常,因为这里我们有一个字符串文字,并且 String
原型没有相应的方法。这意味着,您将永远无法首先检测到实际上是字符串文字的数字。
您应该做的是直接扩展 Number
对象,这样您实际上就可以进行适当的检查而不必处理错误:
Number.isFiniteNumber = function(i){
return !Number.isNaN(i) && Number.isFinite(i);
}
Number.isFiniteNumber(8); // returns true
Number.isFiniteNumber("3.141"); // returns true
Number.isFiniteNumber(".2e-34"); // returns true
Number.isFiniteNumber(Infinity); // returns false
// just for informational purposes
typeof Infinity === "number" // is true
奖金 material:
Extending native objects is potentially dangerous.
Number.isNaN()
probably does not what you think it does.