Object.assign()不操作原型链属性,仅复制源对象自身可枚举属性;赋值时可能触发原型上的setter;新对象默认继承Object.prototype;不当使用可能导致原型链污染。

原型链本身不直接参与 Object.assign() 的执行过程,因为该方法只操作对象自身的、可枚举的自有属性,完全忽略原型上的属性。但理解两者的关系,能帮你避开污染、误拷贝和继承失效等常见问题。
Object.assign 不会读取原型链上的属性
Object.assign() 只遍历源对象(source)的 自身 + 可枚举 属性,即满足 obj.hasOwnProperty(key) && Object.propertyIsEnumerable(key) 的键值对。原型链上的属性(比如从 Object.prototype 或自定义 prototype 继承来的方法或数据)一律跳过。
- 例如:
const parent = { say() { return 'hi'; } }; const child = Object.create(parent); child.name = 'Alice'; Object.assign({}, child)→ 结果只有{ name: 'Alice' },say不会被复制 - 即使你手动在原型上加了可枚举属性(不推荐),
Object.assign依然不会取它——它只认hasOwnProperty
目标对象的原型链可能影响 setter 行为
虽然 Object.assign() 不读原型,但它在给目标对象(target)赋值时,会触发目标对象上已定义的 setter(如果该属性有 setter)。而 setter 可能定义在原型上。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 比如:
const proto = { set name(val) { console.log('set via proto'); this._name = val.toUpperCase(); } }; const target = Object.create(proto); Object.assign(target, { name: 'bob' });→ 会触发原型上的 setter - 这说明:赋值动作走的是 [[Set]] 内部机制,而 [[Set]] 会沿原型链查找 setter,但
Object.assign本身并不“知道”原型链存在
用 Object.assign 实现浅拷贝时,新对象默认继承 Object.prototype
当你写 Object.assign({}, source),第一个参数 {} 是字面量对象,它的 __proto__ 默认指向 Object.prototype。所以拷贝后的新对象仍保有 toString、hasOwnProperty 等方法。
立即学习“Java免费学习笔记(深入)”;
- 但注意:如果你用
Object.assign(Object.create(null), source),得到的对象就没有原型,调用toString()会报错 - 这种写法常用于创建“纯数据字典”,避免被原型属性干扰(如防止原型污染攻击)
原型链污染风险与 Object.assign 的关系
当源对象可控(如来自用户输入或 JSON 解析),且你用 Object.assign(target, userInput),而 userInput 包含 __proto__.polluted = true 这类结构,就可能污染目标对象的原型(尤其在旧版 Node.js 或未加固环境中)。
- 原因:某些运行时会把
__proto__当作特殊键,在赋值时修改目标对象的内部[[Prototype]] - 防范方式:不用
Object.assign合并不可信数据;或先过滤掉__proto__、constructor、prototype等敏感键;或使用Object.create(null)作目标 - 现代环境(如较新 V8)已限制
__proto__的赋值行为,但逻辑层仍需防御性处理

















