JavaScript内置原型的已有方法不可重写、删除或重新配置,因其writable和configurable均为false;但允许安全添加新方法,如Array.prototype.last。

JavaScript 中内置对象的原型(比如 Array.prototype、String.prototype)本质上是可读写的对象引用,但它的属性描述符(property descriptors)默认设为 non-configurable 且 non-writable,这决定了你“能改什么”和“不能改什么”。
关键不是原型本身被锁死,而是它的已有方法和属性被严格保护;而你仍可以安全地添加新方法——只要不破坏规范约束。
内置原型的只读性体现在哪儿
-
Array.prototype.push、String.prototype.split等原生方法本身是 不可重写、不可删除、不可重新配置 的:Object.getOwnPropertyDescriptor(Array.prototype, 'push'); // { value: [Function: push], writable: false, enumerable: false, configurable: false } -
尝试覆盖会静默失败(非严格模式)或报错(严格模式):
'use strict'; Array.prototype.push = function() {}; // TypeError: Cannot assign to read only property -
也不能用
Object.defineProperty修改其特性:Object.defineProperty(Array.prototype, 'push', { writable: true }); // TypeError
为什么还能扩展?哪些操作是允许的
你可以在 Array.prototype 上新增自定义方法,因为新增属性不受已有属性 descriptor 限制:
Array.prototype.last = function() {
return this[this.length - 1];
};
[1, 2, 3].last(); // 3 ✅
✅ 允许的操作:
- 添加新属性(方法或数据属性)
- 使用
Object.defineProperty定义新属性(只要键名未被占用) - 使用
Object.defineProperties批量添加
❌ 不允许的操作:
- 覆盖/重赋值已有原生方法(如
map、filter) - 删除已有原生方法(
delete Array.prototype.map返回false) - 修改已有原生方法的
writable/configurable特性
注意:虽然技术上允许扩展,但不推荐污染内置原型。它会影响全局作用域,可能与未来标准冲突,或与其他库产生行为不一致。
替代方案:更安全的扩展方式
如果目标是增强数组能力又不想动 Array.prototype,可用以下方式:
-
封装成独立工具函数:
const arrUtils = { last(arr) { return arr[arr.length - 1]; } }; arrUtils.last([1,2,3]); // 3 -
使用类继承(ES6+):
class MyArray extends Array { last() { return this[this.length - 1]; } } new MyArray(1,2,3).last(); // 3 借助
Symbol.species或静态方法模拟链式调用,避免实例污染。
小结:只读 ≠ 完全封闭
Array.prototype 这类内置原型不是“只读内存”,而是受 ECMAScript 规范保护的共享对象:
它的设计意图是保障语言一致性与向后兼容——已有接口必须稳定,但开放空间给开发者合理延展。
真正需要警惕的,不是“能不能加”,而是“该不该改原生行为”。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











