Array.prototype.unshift方法详解
前言⁍
最近看到这么一道面试题
输出以下代码执行的结果并解释为什么[1]
1 | |
试了一下,结果如下:
1 | |
这是因为push 方法根据 length 属性来决定从哪里开始插入给定的值。[2]
之后好奇试了一下pop和shift方法,pop属性也是根据length属性来决定位置,而shift属性总是从第一个位置开始移除元素。所以这两个方法的结果都是只有length减少,直至0,就不变了。
问题⁍
问题就出在unshift方法上。
1 | |
当我们移入0时,位于下标2的3被删除了,而位于下标3的4却没变。感觉和想象的不太一样。
分析⁍
对于这个方法,mdn上的描述是:[3]
unshift()方法将一个或多个元素添加到数组的开头,并返回该数组的新长度。
看上去没什么,不过mdn还给出了它的ECMAScript规范[4]其中是这么写的
- 1. Let O be ? ToObject(this value).
- 2. Let len be ? LengthOfArrayLike(O).
- 3. Let argCount be the number of elements in items.
- 4. If argCount > 0, then
- a. If len + argCount > 253 - 1, throw a TypeError exception.
- b. Let k be len.
- c. Repeat, while k > 0,
- i. Let from be ! ToString(𝔽(k - 1)).
- ii. Let to be ! ToString(𝔽(k + argCount - 1)).
- iii. Let fromPresent be ? HasProperty(O, from).
- iv. If fromPresent is true, then
- v. Else,
- 1. Assert: fromPresent is false.
- 2. Perform ? DeletePropertyOrThrow(O, to).
- vi. Set k to k - 1.
- d. Let j be +0𝔽.
- e. For each element E of items, do
- 5. Perform ? Set(O, “length”, 𝔽(len + argCount), true).
- 6. Return 𝔽(len + argCount).
虽然没有完全看懂,但翻译成人话,大概是这么个流程

对于原题中的数组来说,一开始from是1,此时数组中不存在下标为1的值,所以要把to也就是2-1+1=2下标处的值(即'2':3)删除掉;k-1后为1,from变为0,也不存在,k继续减至0。从0开始移入新加入的值,结果就是
{'0':0,'3':4}
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 若叶!



