JavaScript数组方法如push、map、includes均定义在Array.prototype上,所有数组实例通过[[Prototype]]链共享该原型;其原型链为Array.prototype → Object.prototype → null;不推荐直接修改内置原型。

JavaScript 中的 push、map、includes 这些方法,并不“长在”每个数组身上,而是统一存放在 Array.prototype 上。理解这一点,就抓住了原生方法来源的核心。
所有数组共享同一个原型对象
当你写 let arr = [1, 2, 3],引擎实际做了两件事:
— 创建一个新对象(含 length 和索引属性);
— 把它的内部 [[Prototype]] 指向 Array.prototype。
这意味着:
-
arr.push并不是 arr 自己的属性,而是通过原型链向上找到的 - 哪怕创建一百个数组,也只有一份
push方法,节省内存 -
arr.__proto__ === Array.prototype返回true
原型链最终归于 Object.prototype
数组的方法不止来自 Array.prototype,它还能用 toString、hasOwnProperty 等通用方法——这些来自更上层:
-
Array.prototype.__proto__ === Object.prototype是true -
Object.prototype.__proto__是null,链在此终止 - 所以调用
[].toString()实际走的是:数组 → Array.prototype → Object.prototype → 找到toString
验证方法归属的常用方式
你可以直接检查某个方法是否定义在某一级原型上:
-
Array.prototype.hasOwnProperty('map')→true -
Object.prototype.hasOwnProperty('map')→false -
typeof [].map是"function",但typeof [].map === typeof Array.prototype.map为true
也可以用 Object.getPrototypeOf() 逐级查看:
Object.getPrototypeOf([1,2]) 得到 Array.prototypeObject.getPrototypeOf(Array.prototype) 得到 Object.prototype
不要随意修改内置原型
虽然技术上可以给 Array.prototype 添加方法(比如 Array.prototype.sum = function(){...}),但不推荐:
- 可能与其他库或未来标准方法名冲突
- 影响
for...in遍历(除非用Object.defineProperty设置enumerable: false) - 团队协作中降低可预测性,调试困难
如需扩展功能,优先考虑工具函数、类封装或静态方法(如 Utils.arraySum(arr))。










