假设我有两个字面值:false
和1
。如果我在它们两个上调用函数toString()
,我得到:
false.toString() // false
1.toString() // Uncaught SyntaxError: Unexpected token ILLEGAL
什么错误在第二种情况下发生而在第一种情况下没有发生?
使用..
基本上,1
是一个数字,所以如果它后面紧跟着一个小数,它就会被当作浮点量,并期望后面跟着一个小数值(如1.0
)。
1..toString()
可以工作,因为1.
是有效的数字文字,它知道如何处理下一个点来访问对象的属性。这意味着:
1.1.toString(); // Works
1.toString(); // "toString()" isn't a number so we get an error
使用[]
var toString = "toString";
现在你可以这样做:
1[toString]();
使用()
可以用括号括起来。这与声明变量的方式类似:
var a = 5;
a.toString();
(5).toString();
为什么这个工作?
这是因为只有当存在
.
时,它才会期望下面的是数字。
<标题> 错误
如果你在控制台上输入1.toString()
(我使用Safari)。应该是:
At least one digit must occur after a decimal point
表示等待一个数字。
该怎么办?
因为做..
或添加额外的括号会很烦人。您可以使用 String
函数来解决这个问题:
String(1);
标题>实际上,数字是对象字面量。只是需要在数字周围加上括号,以便控制台完成对数字的解析。这样,.
就不会被误认为是小数点。您还可以输入.
s,一个用于小数点,一个用于.toString()
:
//This outputs "2":
console.log((2).toString());
//So does this:
console.log(2..toString());
var hello = 2;
//So does this:
console.log(hello.toString());
关于这个解析错误的更多信息,请查看@vihan的回答。
在JavaScript中,每种类型都有一个原型。对于true
和false
,有Boolean
原型。对于像1
这样的数字,有Number
原型。对于像"Hi!"
这样的字符串,有String
原型。然而,布尔值、数字和字符串都是基本对象,这意味着它们是不可变的,这意味着你不能像普通对象那样对它们设置属性:
var hello = 2;
//hello is a Number object and can have properties and methods like .toString():
console.log(hello.toString());
//This doesn't work, however, because while hello is an object, it is immutable:
hello.hello = 2;
//This outputs undefined because the above didn't work:
console.log(hello.hello);
相反,数组(来自Array
原型),函数(来自Function
原型)是可变对象,所以你可以在它们上面设置属性。此外,像{regular: true}
这样的常规对象是从Object
原型派生的,并且也是可变的。
var arr = [1, 2];
//arr is mutable, so this works just fine and outputs 2:
arr.hello = 2;
console.log(arr.hello);
因此,JavaScript中的所有文字都是对象,但有些是可变的,而另一些是不可变的。您也可以使用Object.freeze()
使常规可变对象不可变,但是使可变对象不可变更加复杂。
需要注意的是,所有这些原型——Boolean
、String
、Number
、Array
、Function
——的都是Object
的后代。这是因为所有原型本身都是对象,因此必须继承Object
。这就像在Java中,所有的类都以某种方式从Object
派生。然而,有一种方法可以使用__proto__
来摆脱Object
的降序,但这更令人困惑,如果你只是进入JavaScript,可能不太好进入。
我希望这个解释能帮助你更好地理解JavaScript !