JavaScript 数组的长度是什么类型的积分?有环绕的危险吗?

What type of integral is a JavaScript array's length? Is there danger of wraparound?

我的意思是:

我有一个函数,我正在写

function unstable_partition ( arr, piv ) 
{
   // puts all values less than piv on the left of arr and 
   // all values greater than or equal to piv on the right side
   var i = 0, j = arr.length - 1;
   while (i < j)
   {
      if (arr[i] <= piv) ++i;
      else if (arr[j] >= piv) --j;
      else swap(arr,i,j);
   }
}

而且我想知道

是否有任何危险
j = arr.length - 1

部分。因为我知道在 C++ 中,例如,保存数组大小的整数类型 size_t 是无符号的,所以如果该值是 0 那么 0 - 1 等于 ~0(最大的 size_t),这会导致此特定函数出现错误。

现在,我知道如果我这样做,我什至不必担心这个

function unstable_partition ( arr, piv ) 
{
   // puts all values less than piv on the left of arr and 
   // all values greater than or equal to piv on the right side
   var len = arr.length;
   if (len === 0) return;
   var i = 0, j = len - 1;
   while (i < j)
   {
      if (arr[i] <= piv) ++i;
      else if (arr[j] >= piv) --j;
      else swap(arr,i,j);
   }
}

但后来我失去了紧凑,优雅。

j = arr.length - 1是否构成危险?

Does j = arr.length - 1 pose a danger?

没有。所有数字在 JS 中都被视为 64 位浮点数(尽管这可能会被引擎优化,只要它们是小整数)。当您从 0 中减去 1 时,您将始终得到 -1.

正如您询问的 arr.lengththe spec says "Every Array object has a length property whose value is always a nonnegative integer less than 232". So it internally may be stored as an unsigned 32 bit integer, and on setting .length a value is actually casted to one,但您可以放心,该数字将适合算术运算所使用的 64 位浮点数。

lengththe spec as an unsigned 32-bit integer 中定义。但是,任何数学运算都会将其强制转换为数字,因此您最终会得到 -1:

[].length - 1 // = -1

将负数分配给长度应该会引发错误。尝试从数组中获取负数会 return undefiend 除非你在数组上创建了一个 属性 具有该名称的名称,这是可能的,因为数组只是具有魔法的对象 属性 这比他们拥有的最大正整数 属性 大一。

a = []
a[-2] = 'something'
a[-1] //undefined
a.length //0
a[10] = 'something'
a.length //11

JavaScript 只有一种数字类型 - Number - 对应于 64 位 IEEE-754 浮点数(C++ 中的 double 类型),但只有一个 NaN 值。所以没有用 arr.length - 1

环绕的危险

数组的 "length" 属性 return 是一个数字,并且仅限于 0 ... 2^32-1 范围内的整数值。

Every Array object has a length property whose value is always a nonnegative integer less than 2^32. ECMAScript 2015

所以arr.length - 1总是return-1或0或小于2^32-2的正整数。

(顺便说一句,2^53-1 是在 +1 之类的操作开始失去精度之前可以安全地存储在数字中的最大整数。ECMAScript 标准的各个部分都使用它作为限制,例如定义Array.prototype.push 但数组 "length" 属性 被进一步限制。)