面试必考!JavaScript Object.create vs Object.assign的本质区别与实战秘籍

274 阅读2分钟

一、Object.create —— 原型链的魔法师

1.1 语法与功能

const newObj = Object.create(proto, [propertiesObject]);

它的最大特性,是可以精确控制新对象的原型([[Prototype]])。不像{}这种方式,无法动态指定原型!

1.2 适用场景

  • 原型继承:构造函数/类之外的原型继承利器。
  • 简写继承链:无需 new,也不需要 call/apply。

1.3 实战案例

const LivingThing = { eat() { console.log('I can eat!'); } };
const Animal = Object.create(LivingThing);
Animal.bark = function () { console.log('I can bark!'); };

const dog = Object.create(Animal);
dog.name = "Buddy";
dog.bark(); // I can bark!
dog.eat();  // I can eat!
console.log(Object.getPrototypeOf(dog) === Animal); // true

你会发现,原型链可以无限层级,继承如丝般顺滑!


二、Object.assign —— 对象扩展的王牌

2.1 语法与功能

Object.assign(target, ...sources)

它的作用是浅拷贝+属性合并,让多个对象属性融合成为一体。

2.2 适用场景

  • 配置合并:合并默认配置和用户自定义配置。
  • 拷贝对象:浅拷贝新对象,防止污染原对象。
  • 多态拓展:为对象动态加入方法与属性。

2.3 实战案例

const defaultOpt = { color: 'blue', size: 'M' };
const userOpt = { size: 'L', price: 199 };
const settings = Object.assign({}, defaultOpt, userOpt);

console.log(settings); // { color: "blue", size: "L", price: 199 }

注意点: 如果属性值是对象或数组,只会拷贝引用,真正需要深拷贝要用其它方法!


三、底层机制 —— 一字之差,天壤之别

Object.createObject.assign
原型链设置新对象的__proto__保持目标对象原型不变
赋值不把原型上的属性拷贝到新对象只复制源对象自有的可枚举属性
类型返回新对象直接修改目标对象并返回

四、面试官最爱问的高级题 & 易混淆点揭秘

4.1 问:能不能用 Object.assign 实现继承?

答:不能,Object.assign 只会复制属性,不会改变 [[Prototype]]。继承链不会改变。

const base = { a: 1 };
const child = Object.assign({}, base);
console.log(Object.getPrototypeOf(child) === base); // false

4.2 问:Object.create 会拷贝属性吗?

答:不会,只设置新对象的原型,不全部复制属性。属性还是需要后续赋值实现。

4.3 问:怎么用 Object.create + Object.assign 实现深度“继承+组装”?

const proto = { greet() { console.log('Hi!'); } };
const customProps = { age: 22, name: 'Alice' };
const person = Object.assign(Object.create(proto), customProps);
person.greet(); // Hi!

这样就拥有了继承+特性扩展的最佳实践!


结语

如果你觉得这篇文章有用,记得点赞、收藏、分享,关注我查看更多前端干货!