JavaScript 中 Number 方法的奇怪语法
Posted
技术标签:
【中文标题】JavaScript 中 Number 方法的奇怪语法【英文标题】:Strange syntax of Number methods in JavaScript 【发布时间】:2010-12-24 01:51:38 【问题描述】:看看下面的代码:
Number.prototype.isIn = function ()
for (var i = 0, j = arguments.length; i < j; ++i)
if (parseInt(this, 10) === arguments[i])
return true;
return false;
;
var x = 2;
console.log(x.isIn(1,2,3,4,5)); // <= 'true'
console.log(2.isIn(1,2,3,4,5)); // <= Error: 'missing ) after argument list'
为什么当它是一个变量时,代码可以正常工作,而当它是数字文字时,它会失败?
而且,奇怪的是,为什么下面的行有效?
console.log((2).isIn(1,2,3,4,5)); // <= 'true'
在上面一行中,我基本上将文字括在括号中。
【问题讨论】:
【参考方案1】:这是一个语法错误,因为您代表的是一个数字。字符串可以这样工作,但数字不能,因为紧跟在数字后面的句点象征着十进制值。 .
后面的字符导致错误。
【讨论】:
【参考方案2】:大多数答案已经表明,数字文字后的点被视为该数字的一部分,作为分数分隔符。但是,如果您仍想将点用作运算符,那么快速简便的解决方法是在数字和空格之间留一个空格。
2 .isIn(1,2,3,4,5) // <- notice the space between 2 and .
【讨论】:
其实这很合乎逻辑——点是 javascript 中的标准运算符,就像 + 或 = 或 - 一样。您可以编写类似 4 + 5 的内容,以便使用 4 。 isIn() 也是如此。 @Andris,很好的答案。然而,请注意,添加括号更好 (2).isIn(1,2,3,4,5,6) (在可读性意义上)【参考方案3】:Josh 是正确的,但你不必使用变量来使用数字方法, 虽然这样做通常更方便。
5.isIn(1,2,3,4,5) returns an error
5.0.isIn(1.2.3.4.5) returns true, as does
(5).isIn(1,2,3,4,5)
【讨论】:
5..isIn
和 5 .isIn
也消除了 [parsing] 歧义。【参考方案4】:
尽管由于自动类型转换,区别通常不明显,但 JavaScript 支持许多基本类型以及对象:
var foo = 10;
var bar = new Number(10);
alert(foo.toString(16)); // foo is automatically wrapped in an object of type Number
// and that object's toString method is invoked
alert(bar.toString(16)); // bar is already an object of type Number,
// so no type conversion is necessary before
// invoking its toString method
var foo2 = "foo";
var bar2 = new String("foo");
alert(typeof foo2); // "string" - note the lowercase "s", not a String object
alert(typeof bar2); // "object"
alert(typeof true) // "boolean"
alert(typeof new Boolean(true)) // "object"
还有一些真正让问题感到困惑的东西:
// the next line will alert "truthy"
alert("Boolean object with value 'false'" + (new Boolean(false) ? " is truthy" : " is falsy"));
// the next line will alert "falsy"
alert("boolean primitive with value 'false'" + (false ? " is truthy" : " is falsy"));
虽然依靠自动类型转换让生活更轻松一些,但人们应该始终牢记对原始值和对象实际上是什么类型的良好理解;令人惊讶的大量 JS 错误的出现是因为人们没有意识到,例如,看起来像数字的东西实际上是一个字符串,或者他们执行的某些操作导致了曾经包含数字的东西被分配了一个新值,它是一个字符串或一个对象。
编辑:为了更仔细地解决原始问题,我现在意识到我没有明确回答:10.foo()
将导致语法错误,因为.
被视为小数点,而foo()
不是' t 要被解析为数字的有效字符序列。 (10).foo()
将作为封闭括号 (10)
使 .
之前的整个构造成为一个表达式。计算此表达式并返回原始数值 10
。然后.
被视为在对象上下文中处理该原始值,因此它会自动包装在Number
类型的对象中(这是自动类型转换的作用)。然后引用该对象的原型链上的foo
属性;最后的()
导致该属性被视为函数引用,并在遇到.
时包裹在原始值周围的Number 对象的“this”上下文中调用。
【讨论】:
10
和 Number(10)
是相同的。 bar = Number(10)
不会使 bar
成为“数字类型的对象”。也许您打算将10
与new Number(10)
进行比较?或 '10'
与 Number('10')
?
哎呀,好消息 - new
不见了。我应该从我进行测试的控制台中复制这些东西,而不是重新输入它:-)【参考方案5】:
我的理解是数字是文字,不是一个对象。但是,当您将变量定义为数字时,它就会变成一个新的 Number() 对象。
所以执行以下操作;
var x = 10;
和去一样;
var x = new Number(10);
至于第二个例子;我只能假设将括号括在数字周围使 JavaScript 编译器假定该值是匿名 Number() 对象。我猜这是有道理的......
【讨论】:
x = 10
和 x = new Number(10)
不等价。
正确:alert(typeof 10);
与 alert(typeof new Number(10));
以上是关于JavaScript 中 Number 方法的奇怪语法的主要内容,如果未能解决你的问题,请参考以下文章