貌似判断数组可以用arr.length === + arr.length,所以想了解一下js内部length的实现
主流的库使用的判断方法是Object.prototype.toString.call(arr) === '[object Array]';
ES5以上环节可以用Array.isArray(arr)
这样
至于LZ标题里所说的“怎么实现的”,我认为有两种办法
1. 引擎通过native实现
2. 通过Object.defineProperty
定义它的getter/setter函数内维护这个属性
判断数组可以用
arr.length === + arr.length
不知道你從哪看(聽)來的,很遺憾,這是不對的, 比如:
(function(a,b,c){}).length === + '345'.length
為 true
其實,該判斷還需要前提: typeof arr === typeof []
. 另外還考慮到 arguments
這個奇葩的存在(感謝 @mcfog 提醒), 需要另外加上 !arr.callee
的判斷. 所以完整的是:
typeof arr === typeof [] && !arr.callee && arr.length === + arr.length
為什麼?因為對 Object 或者 Array 作 typeof
運算得到的值都是 "object"
, 造成了混淆。
但是這兩者還是有區別的,體現在 Array 有 length
屬性而 Object 沒有.
+ arr.length
等價于 0 + arr.length
, 如果 arr
不是數組,那麼 arr.length
就是 undefined
, 嘗試把 undefined
轉換為數字就會得到 NaN
, 顯然 undefined !== NaN
, 即可知 arr
為 Object.
Ps. 這跟內部實現沒有關係。
想了解一下js内部length的实现
8 回答4.6k 阅读✓ 已解决
6 回答3.3k 阅读✓ 已解决
5 回答2.8k 阅读✓ 已解决
5 回答6.3k 阅读✓ 已解决
4 回答2.2k 阅读✓ 已解决
4 回答2.7k 阅读✓ 已解决
3 回答2.4k 阅读✓ 已解决
arr.length === + arr.length
的确是一种鸭式辨型的判断方法。这句话包含两层意思:
1.
arr
有length
这个属性2.
arr.length
是一个Number
(可以试一下x === +x
)鸭式辨型的经典假设:只要是会游泳的鸟类,不管它是什么,我都把它当成鸭子。
鸭式辨型在楼主例子中的假设:只要
arr
有length
这个属性,且它是个Number
,我都把arr
当成是数组。这种鸭式辨型的判定方法,要看你的具体需求!!比如你并不在乎其他事,只关心要使用的这个变量必须满足上面的两个条件,就可以这么判断。
因为字符串有
length
这个属性,且它的length
是个Number
。所以如果你用了arr.length === + arr.length;
来判断数组,字符串也满足这样的条件。如果在你的开发场景中,只关心这两个条件,当然就没问题。如果你要求必须是个数组,就不能用这种鸭式辨型的方法来判断了。据说jQuery中要判断一个变量是否是一个数组的确切方法是:
关于鸭式辨型更多的了解,可以参考《javascript权威指南》中的描述
关于js内部是如何实现Array的length的。我想楼主可以参考MDN的文档:《Array.length》