不能直接提取原型链属性到自身,本质是复制或重新定义以切断依赖;目的包括防原型误改、提性能、保实例独占;数据属性可直接赋值,对象/数组需防浅拷贝,函数须bind或封装,检查自有属性用object.hasown()。

不能直接“把原型链上的属性提取到自身”,因为原型链是查找机制,不是存储容器。所谓“提取”,本质是复制或重新定义——即在对象自身上创建同名属性,切断对原型的依赖。
明确目的:为什么要从原型链拿到自身?
常见动机有三个:避免原型被意外修改影响所有实例、提升属性访问性能(跳过原型查找)、实现属性值的实例独占(比如每个实例需要独立副本)。
安全复制属性到自身
推荐用 Object.assign() 或直接赋值,前提是确认该属性可枚举且非函数(函数通常需绑定 this):
- 若属性是数据属性(如
name),直接赋值即可:obj.name = obj.name; - 若属性来自原型且是对象或数组,注意浅拷贝风险:
obj.config = { ...obj.config }; - 若需批量操作,可用
Object.getOwnPropertyNames()获取当前层级属性,再结合Object.getPrototypeOf()沿链查找目标属性并复制
函数方法的正确“提取”方式
方法不能简单赋值,否则会丢失 this 绑定。正确做法是显式绑定或封装:
- 用
bind创建绑定版本:obj.sayHello = obj.sayHello.bind(obj); - 封装为箭头函数或普通函数:
obj.sayHello = () => this.sayHello();(需确保上下文正确) - 更稳妥的是在构造函数中初始化:
this.sayHello = this.sayHello.bind(this);
避免踩坑的关键细节
不要修改原型本身;不要依赖 for...in 判断属性来源(它会遍历整个链);要用 hasOwnProperty() 或 Object.hasOwn() 确认属性是否已在自身存在:
if (!Object.hasOwn(obj, 'prop')) obj.prop = obj.prop;- 对不可写/不可配置的原型属性,强行赋值可能静默失败,应先检查
Object.getOwnPropertyDescriptor()











