为什么数组Array可以直接调用方法,而普通的Object对象却不行?

比如我们可以这样数组排序:

[1,2,3].sort()

却不能这样调用对象的方法:

{}.toString()

还有,为什么字符串可以直接调用方法,Number类型、Boolean类型却不行。

字符串我了解一些,调用字符串方法的时候会生成一个临时的String对象,Number、Boolean类型为啥不行?

阅读 4.5k
3 个回答

这不和eval()解析'{}'道理一样,js解析代码会优先把{看成和function{}的大括号一样,会分开解析先解析{(开始),在解析}(结束)。这样的话当然会报错了。
eval()解析'{}'时是怎么办的,加个括号'({})';这样就会把{}看成一个整体来解析,这时候它就是对象了。
至于“为什么字符串可以直接调用方法,Number类型、Boolean类型却不行”
Boolean类型可以呀,
至于数字不能直接调用方法,那也是js解析的原因,比如

8.toString()//报错
(8).toString()// 正确
8.0.toString()// 正确

那为什么呢,因为js中不存在真正的整数,整数都是用浮点数表示的,所以当js解析8是发现后面还有.于是会把8.看成一个数,这样的话没加.toString当然错了。
所以如果写成下面这样也可以

8..toString()// 正确

首先你的想法是错误的.普通的 Object 对象是可以调用方法的.如

var o = {};
o.toString(); // OK

但是{}.toString()却是出现语法错误,因为{}.toString()中的{}将会被看成一个语句块,而不是对象直接量.
因为 JavaScript 将从左到右解析{}.toString(),当遇到{时,它将会看做一个语句块的开始,之后遇到},语句块结束,在遇到.将会发生语法错误.

而如果使用({}).toString()将可以正常工作.(注意包围在{}两边的括号).
因为当解析({}).toString()时,首先遇到(,则将括号里面的部分看做表达式,得到一个空对象,因此对这个空对象执行方法调用是合法的.

关于 {}.toString() 这个问题,有人已经讲得非常清楚了。是因为 js 引擎在解析时,会把{}当成块标记。不过我表示也很奇怪,楼主说的问题,我在mac上试了几个浏览器都没有问题。

我想补充的是楼主的第二个问题,为什么字符串可以直接调用方法,Number类型、Boolean类型却不行。 我想,你应该是哪里搞错了。

var num = 1.2333;
var flag = true;
            
console.log({}.toString())   //[object, object]
console.log(num.toFixed(2));  //1.23
console.log(flag.toString()); //'true'   这里是字符串

这里,num是个数值字面量,flag是个布尔值,它们俩都可以调用方法。楼主对字符串了解一些,那应该明白,基本类型的数据本来就没有属性和方法的,只有对象才拥有。

但是为什么我们又可以像调用对象的方法一样来调用基本数据类型的方法呢?(如: 'a bc'.trim())

是因为,基本数据类型的值在调用方法时,js 会将其转为一个临时包装对象。字符串直接量就可以像字符串对象(new String('abc'))一样调用属性和方法,数值字面量就可以像数值对象一样调用属性和方法。

当然,这个临时包装对象只在代码执行的这一瞬间存在。方法执行完毕,这个临时对象就立即销毁。

所以楼主说的,Number, Boolean类型的值不可以调用方法是不可能的。

推荐问题
宣传栏