检查属性名是否为数组索引

4

我想为一个数组分配一些属性,但前提是它们是数组索引。否则,某些实现可能会将底层结构切换到哈希表,而我不想这样。

例如,这些是数组索引:"0""1""2""3""4""4294967294"

但这些不是:"abcd""0.1""-0""-1"" 2""1e3""4294967295"

有没有一种简单的方法来测试一个字符串是否是数组索引?

1个回答

7
在ECMAScript 5中,数组索引定义如下:Array indices

如果一个属性名 P(以字符串形式)满足以下两个条件,则它是一个 array index:若ToUint32(P)不等于232−1,且ToString(ToUint32(P))等于P

(在ECMAScript 2015中的定义口径不同但应该是等效的)

那么代码应该是:

function isArrayIndex(str) {
  return (str >>> 0) + '' === str && str < 4294967295
}

逐步地,
  • ToUint32(P) can be done by shifting 0 bits with the unsigned right shift operator

    P >>> 0
    
  • ToString(ToUint32(P)) can be done by concatenating the empty string with the addition operator.

    (P >>> 0) + ''
    
  • ToString(ToUint32(P)) is equal to P can be checked with the strict equals operator.

    (P >>> 0) + '' === P
    

    Note this will also ensure that P really was in the form of a String value.

  • ToUint32(P) is not equal to 232−1 can be checked with the strict does-not-equal operator

    (P >>> 0) !== 4294967295
    

    But once we know ToString(ToUint32(P)) is equal to P, one of the following should be enough:

    P !== "4294967295"
    P < 4294967295
    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接