数组实例通过原型链访问Array.prototype上的方法,而非继承;其原型链为arr→Array.prototype→Object.prototype→null;可向Array.prototype添加方法但不推荐生产使用;普通对象无法真正具备数组行为,复用数组方法应使用call/apply或Array.from等安全方式。

数组本身不“继承”方法,而是所有数组实例的 [[Prototype]] 自动指向 Array.prototype,从而能访问其上的共享方法(如 push、map、filter 等)。这不是手动继承,而是 JavaScript 引擎在创建数组时内置的原型链设定。
数组的原型链结构是固定的
当你写 let arr = [1, 2, 3] 或 let arr = new Array(1, 2, 3) 时,引擎自动完成以下链接:
-
arr.__proto__ === Array.prototype(为true) Array.prototype.__proto__ === Object.prototypeObject.prototype.__proto__ === null
所以完整查找链是:arr → Array.prototype → Object.prototype → null。你调用 arr.push(),实际是在 Array.prototype 上找到该方法;调用 arr.toString() 则一路查到 Object.prototype。
可以向 Array.prototype 添加自定义方法
因为所有数组实例共享 Array.prototype,往它上面挂方法,所有数组都能立即使用:
立即学习“Java免费学习笔记(深入)”;
Array.prototype.last = function() { return this[this.length - 1]; };- 之后
[1,2,3].last()返回3,[].last()返回undefined
⚠️ 注意:不推荐在生产环境直接扩展原生原型,可能引发冲突或影响可维护性;仅用于学习理解原型链机制。
无法让普通对象“变成数组”并继承数组方法
仅靠设置 obj.__proto__ = Array.prototype 并不能使普通对象拥有数组行为:
- 它能调用
push、map等方法,但这些方法内部依赖this.length和索引属性(如this[0]) - 普通对象没有自动维护
length,也不支持数字键自动更新length,因此多数数组方法会失效或返回意外结果 - 真正具备数组行为的对象,必须由
Array构造函数创建,或通过Object.setPrototypeOf(obj, Array.prototype)+ 手动初始化关键属性(不实用,仅理论可行)
想复用数组方法?用 call/apply 或 Array.from
如果有一个类数组对象(如 arguments、NodeList),想用数组方法,推荐安全方式:
-
Array.prototype.slice.call(arrayLike)(ES5) -
Array.from(arrayLike).map(...)(ES6+,更清晰) -
[...arrayLike].forEach(...)(展开运算符)
这些方式不修改原型链,而是借用方法并正确绑定 this,稳定可靠。


















