【问题标题】:SyntaxError when extending Number object扩展 Number 对象时出现 SyntaxError
【发布时间】:2017-11-10 15:33:22
【问题描述】:

我正在尝试使用以下代码扩展 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!!

【问题讨论】:

  • 你真的不希望 JS 能够区分 8.isNumber 和 8.123456 吗?
  • 好吧,你将无法做到8.anything,因为 JS 语法。 Number.isNumber 不是函数,但 var n = 8; n.isNumber() 可以满足您的期望。 (正如答案所示,您可以使用 () 将其转换为工作版本,这可能不是您想要的语法。但如果您不立即使用它,那很好。
  • @ChrisCaviness 没有理由不能,只是不能。例如,Ruby 可以很好地解析它。
  • 我认为整个概念是有缺陷的。 variable.isNumber() 仅在解析器进行类型检查并接受文字为 typeof variable === "number 时才有效,否则将引发错误。相反,您想要的是直接扩展 Number,而不是原型,以便您可以运行 Number.isNumber(variable)
  • @Christoph Lol,说得好。

标签: javascript syntax-error prototype literals


【解决方案1】:

尽管您已经接受了,但我忍不住提供了一个额外的答案。

您需要了解的第一件事是,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

奖励材料:

Extending native objects is potentially dangerous.

Number.isNaN() probably does not what you think it does.

【讨论】:

    【解决方案2】:

    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);
    }

    【讨论】:

    • “尝试推杆”并不是一个很有说服力的答案。为什么它起作用?解释扩展“数字”原型的含义。什么是文字等...
    • 或使用..,如var x = 8..isNumber()。第一个. 是小数点,第二个. 是对象属性访问器。 (不是我建议这样的用法,仅供参考和理解
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-28
    • 2013-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-03
    相关资源
    最近更新 更多