一、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.create | Object.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!
这样就拥有了继承+特性扩展的最佳实践!
结语
如果你觉得这篇文章有用,记得点赞、收藏、分享,关注我查看更多前端干货!