Maison > Questions et réponses > le corps du texte
貌似判断数组可以用arr.length === + arr.length,所以想了解一下js内部length的实现
伊谢尔伦2017-04-10 14:30:09
arr.length === + arr.length
的确是一种鸭式辨型的判断方法。
这句话包含两层意思:
1. arr
有length
这个属性
2. arr.length
是一个Number
(可以试一下x === +x
)
鸭式辨型的经典假设:只要是会游泳的鸟类,不管它是什么,我都把它当成鸭子。
鸭式辨型在楼主例子中的假设:只要arr
有length
这个属性,且它是个Number
,我都把arr
当成是数组。
这种鸭式辨型的判定方法,要看你的具体需求!!比如你并不在乎其他事,只关心要使用的这个变量必须满足上面的两个条件,就可以这么判断。
var arr = "123";
var arr2 = [1,2,3];
arr.length === + arr.length; //true
arr2.length === + arr2.length; //true
因为字符串有length
这个属性,且它的length
是个Number
。所以如果你用了arr.length === + arr.length;
来判断数组,字符串也满足这样的条件。如果在你的开发场景中,只关心这两个条件,当然就没问题。如果你要求必须是个数组,就不能用这种鸭式辨型的方法来判断了。
据说jQuery中要判断一个变量是否是一个数组的确切方法是:
Object.prototype.toString.call(arr)==='[object Array]'
关于鸭式辨型更多的了解,可以参考《javascript权威指南》中的描述
关于js内部是如何实现Array的length的。我想楼主可以参考MDN的文档:《Array.length》
PHP中文网2017-04-10 14:30:09
判断数组可以用
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的实现
黄舟2017-04-10 14:30:09
关于array的判断,angularJS是这样做的
Object.prototype.toString.call(arr) === '[object Array]'
PHPz2017-04-10 14:30:09
主流的库使用的判断方法是Object.prototype.toString.call(arr) === '[object Array]';
ES5以上环节可以用Array.isArray(arr)
这样
至于LZ标题里所说的“怎么实现的”,我认为有两种办法
1. 引擎通过native实现
2. 通过Object.defineProperty
定义它的getter/setter函数内维护这个属性