Strange syntax of Number methods in JavaScript

匆匆过客 提交于 2019-12-29 01:39:31

问题


Take a look at the following code:

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'

Why is it that when it's a variable, the code works correctly yet when it is a number literal, it fails ?


And also, strangely enough, why does the following line work?

console.log((2).isIn(1,2,3,4,5)); // <= 'true'

In the above line, I basically enclosed the literal in parenthesis.


回答1:


It's a syntax error because you are representing a number. Strings can work that way, but not numbers, because a period immediately following a number symbolizes a decimal value. The character after the . is causing the error.




回答2:


Most of the answers already stated that a dot after a numeric literal is considered part of this number as a fraction separator. But if you still want to use the dot as an operator then the quick and easy fix would be leaving an empty space between the number and the space.

2 .isIn(1,2,3,4,5) // <- notice the space between 2 and .



回答3:


Josh was correct, but you do not have to use a variable to use a method of a number, although it is usually more convenient to do so.

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)



回答4:


Although the distinction is often not apparent because of automatic type conversion, JavaScript supports a number of primitive types as well as objects:

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"

and something that really confuses the issue:

// 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"));

Although relying on automatic type conversion makes life a little easier, one should always have at the back of one's mind a good understanding of what types your primitive values and objects actually are; a surprisingly large number of JS bugs come about because of people failing to realise that, for example, something which looks like a number is actually a string, or that some operation they have carried out has resulted in something that used to contain a number having been assigned a new value that is a string, or an object.

EDIT: to more closely address the original question, which I now realise I hadn't answered explicitly: 10.foo() will cause a syntax error as the . is seen as a decimal point, and foo() isn't a valid sequence of characters to be parsed as a number. (10).foo() will work as the enclosing brackets (10) make the entire construct before the . into a single expression. This expression is evaluated and returns the primitive number value 10. Then the . is seen as treating that primitive value in an object context, so it is automatically wrapped in an object of type Number (this is the automatic type conversion in action). Then the foo property of that object, found on its prototype chain, is referenced; and the final () cause that property to be treated as a function reference and invoked in the 'this' context of the Number object that was wrapped around the primitive value at the point of encountering the ..




回答5:


My understanding goes that numbers are literals, and not an objects. However, when you define a variable as an number, then it becomes a new Number() object.

So doing the following;

var x = 10;

Is the same as going;

var x = new Number(10);

As for the second example; I can only assume that putting the brackets around the number has made the JavaScript compiler assume that the value is an anonymous Number() object. Which makes sense I guess...



来源:https://stackoverflow.com/questions/1860998/strange-syntax-of-number-methods-in-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!