本文教你从零实现 Array.prototype.push 的核心逻辑:正确绑定 this、修改原数组、返回新长度,且不依赖 push、concat 等任何内置数组方法。
本文教你从零实现 `array.prototype.push` 的核心逻辑:正确绑定 `this`、修改原数组、返回新长度,且不依赖 `push`、`concat` 等任何内置数组方法。
在 JavaScript 中,Array.prototype.push() 是一个修改原数组并返回新长度的方法。若需手动实现其行为(例如在算法题、面试手写或学习原型机制时),必须严格遵循其规范:操作 this 指向的数组对象、逐个追加参数、更新 length 属性,并返回最终长度值——而非返回数组本身。
以下是符合标准的纯手工实现(不使用 push、concat、splice 等任何数组方法):
Array.prototype.push2 = function(...items) {
// 1. 确保 this 是数组(可选健壮性检查)
if (!Array.isArray(this)) {
throw new TypeError('this is not an array');
}
// 2. 获取当前长度(即第一个可插入索引)
const len = this.length;
// 3. 逐个将参数赋值到数组末尾
for (let i = 0; i < items.length; i++) {
this[len + i] = items[i];
}
// 4. 更新 length 属性(关键!)
this.length = len + items.length;
// 5. 返回新长度(与原生 push 行为一致)
return this.length;
};✅ 正确用法示例:
const arr = [1, 2, 3]; console.log(arr.push2(72, 12, 41)); // 输出: 6(新长度) console.log(arr); // [1, 2, 3, 72, 12, 41]
⚠️ 常见错误及原因分析:
-
错误写法:source.push2 = function(...) { ... }
→ 将方法挂载到具体实例上,无法被其他数组复用,且 this 在调用时可能丢失(如 const fn = arr.push2; fn() 会报错或误操作全局对象)。 -
错误返回值:return this; 或 return [...this];
→ 原生 push() 始终返回数字类型的新长度,而非数组。测试框架(如 Jest)会严格校验返回值类型与值。 -
未更新 this.length
→ 数组的 length 是自有属性,直接赋值 this[len + i] 不会自动增长 length;必须显式设置 this.length = newLength,否则后续操作(如 for 循环遍历)可能遗漏新元素。
? 进阶提示:
该实现已兼容多参数、空参数([].push2() 返回 0)、稀疏数组(如 [1,,3].push2(4) 正确处理 length)等边界情况。若需支持类数组对象(如 arguments),可进一步增强类型判断,但严格意义上 push 仅定义在 Array.prototype 上。
掌握这一实现,不仅加深对 this 绑定、原型链和数组底层机制的理解,也为你应对“禁用内置方法”的编程挑战打下坚实基础。

















