Home  >  Q&A  >  body text

javascript - JS内部是如何实现Array的length属性的?

貌似判断数组可以用arr.length === + arr.length,所以想了解一下js内部length的实现

PHP中文网PHP中文网2748 days ago481

reply all(6)I'll reply

  • 伊谢尔伦

    伊谢尔伦2017-04-10 14:30:09

    arr.length === + arr.length的确是一种鸭式辨型的判断方法。
    这句话包含两层意思:
    1. arrlength这个属性
    2. arr.length是一个Number(可以试一下x === +x)

    鸭式辨型的经典假设:只要是会游泳的鸟类,不管它是什么,我都把它当成鸭子。
    鸭式辨型在楼主例子中的假设:只要arrlength这个属性,且它是个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》

    reply
    0
  • 怪我咯

    怪我咯2017-04-10 14:30:09

    为啥不用arr instanceof Array 来判断是否是数组呢

    reply
    0
  • PHP中文网

    PHP中文网2017-04-10 14:30:09

    判断数组可以用 arr.length === + arr.length

    不知道你從哪看(聽)來的,很遺憾,這是不對的, 比如:

    (function(a,b,c){}).length === + '345'.lengthtrue

    其實,該判斷還需要前提: typeof arr === typeof []. 另外還考慮到 arguments 這個奇葩的存在(感謝 @mcfog 提醒), 需要另外加上 !arr.callee 的判斷. 所以完整的是:

    typeof arr === typeof [] && !arr.callee && arr.length === + arr.length


    為什麼?因為對 Object 或者 Arraytypeof 運算得到的值都是 "object", 造成了混淆。

    但是這兩者還是有區別的,體現在 Arraylength 屬性而 Object 沒有.

    + arr.length 等價于 0 + arr.length, 如果 arr 不是數組,那麼 arr.length 就是 undefined, 嘗試把 undefined 轉換為數字就會得到 NaN, 顯然 undefined !== NaN, 即可知 arrObject.


    Ps. 這跟內部實現沒有關係。

    想了解一下js内部length的实现

    reply
    0
  • 黄舟

    黄舟2017-04-10 14:30:09

    关于array的判断,angularJS是这样做的

    Object.prototype.toString.call(arr) === '[object Array]'
    

    reply
    0
  • PHPz

    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函数内维护这个属性

    reply
    0
  • PHP中文网

    PHP中文网2017-04-10 14:30:09

    占楼。我不说话。

    reply
    0
  • Cancelreply