([] + {}).length ?

([]).length // 0

({}).length // undefined

([] + {}).length //15

为什么 ([] + {}).length 是15?

阅读 6.5k
5 个回答

([]).length --> 空数组的length是0

({}).length --> {}是一个空对象,这个对象是没有length 方法的所以是undefined

([] + {}).length --> 实际这两个是不能用操作符"+"的,这个表达式实际是分别调用了[]和{}的toString()方法。[]返回空字符串"",而{}返回"[object Object]",这两个字符串拼在一起刚好是15个字符的一个字符串。

可以这样验证:
([]).toString() // ""
({}).toString() // "[object Object]"
([]+{}) // "[object Object]"

[] + {} 运算,首先是调用对象的 valueOf 方法,如果返回一个基本类型,则以该基本类型参与运算;否则调用 toString 方法,返回基本类型则参与运算。

数组和对象的 valueOf(默认)返回自身,因此不是基本类型,接着调用 toString,空数组返回空字符串,普通对象始终返回字符串 [object Object]。故视为两个字符串的拼接,结果为字符串 [object Object],其长度为 15。

一个例外是 Date 的实例,其实例首先调用 toString ,接着才调用 valueOf

题主可试着为这些对象添加自己的 valueOf 或者 toString 方法,比如让它们返回一个数字,结果就是两个数字相加,变成加法运算而不是字符串拼接了。

clipboard.png
[]+{}先尝试valueOf()方法,如果返回的不是基本类型 ,再调用toString()方法

[].valueOf()
//[]
({}).valueOf()
//Object {}
[].toString()
//""
({}).toString()
//"[object Object]"
([] + {})
//"[object Object]"
"[object Object]".length
//15

@miracledan 给出了解决方案。但我想说的是:接触到前端,底层基础原理很重要。多花点时间去思考。
比如说([] + {}).length这个问题首先切入点是 ([]+{}) 是什么,控制台一打印出来就很容易理解了。

clipboard.png

另外如果数组有内容的toString 是 [1,2] => "1,2"

最后,楼主最好是别纠结这些东西,也别写这种代码。因为1可阅读很重要,别人看不懂;2说不定不同浏览器处理还不同。

这种代码只能用来分析吧,平时谁会写这样的代码呢

推荐问题
宣传栏