You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

JavaScript:Object.create与Object.assign实现原型继承的区别及疑问

Why Use Object.create(Sup.prototype) Instead of Object.assign({}, Sup.prototype) for JavaScript Inheritance?

Great question! This is a super common point of confusion when learning prototype-based inheritance in JavaScript. Let’s break down the core differences between these two approaches and why Object.create(Sup.prototype) is the standard go-to.

Key Difference: Prototype Chain vs. Static Property Copy

The entire point of JavaScript inheritance is the prototype chain—the ability for an object to access properties and methods from its parent prototype, even as that parent prototype evolves. Let’s look at how each method handles this:

1. Object.create(Sup.prototype): Builds a Live Prototype Chain

When you run Sub.prototype = Object.create(Sup.prototype), you’re creating a new object whose hidden internal [[Prototype]] reference points directly to Sup.prototype. This establishes a dynamic, live link between the child and parent prototypes:

  • Any new methods or properties added to Sup.prototype later will automatically be accessible to instances of Sub (as long as the instance doesn’t override them).
  • The instanceof operator works as expected: a Sub instance will correctly be recognized as an instance of Sup.
  • Even non-enumerable properties on Sup.prototype are accessible via the prototype chain.

2. Object.assign({}, Sup.prototype): Only Copies Enumerable Properties

Object.assign({}, Sup.prototype) creates a blank object and copies all enumerable own properties from Sup.prototype into it. The catch? This new object’s prototype is the default Object.prototype—it has no connection to Sup.prototype at all. This means:

  • Any updates to Sup.prototype after the copy won’t trickle down to Sub instances, since there’s no live prototype chain link.
  • instanceof Sup will return false for Sub instances, because their prototype chain doesn’t include Sup.prototype.
  • Non-enumerable properties on Sup.prototype won’t be copied over, so they’re completely inaccessible to Sub instances.

Concrete Example to See the Gap

Let’s test both approaches with code to highlight the real-world differences:

// Parent constructor
function Sup() {}
Sup.prototype.sayHello = function() { console.log('Hello from Sup!'); };

// Add a non-enumerable property to the parent prototype
Object.defineProperty(Sup.prototype, 'secretProp', {
  value: 'I am hidden',
  enumerable: false
});

// Approach 1: Object.create (proper inheritance)
function Sub1() {}
Sub1.prototype = Object.create(Sup.prototype);
Sub1.prototype.constructor = Sub1; // Fix constructor reference

// Approach 2: Object.assign (property copy, not inheritance)
function Sub2() {}
Sub2.prototype = Object.assign({}, Sup.prototype);
Sub2.prototype.constructor = Sub2;

// Test initial behavior
const sub1 = new Sub1();
const sub2 = new Sub2();

sub1.sayHello(); // Output: "Hello from Sup!" (works via prototype chain)
sub2.sayHello(); // Output: "Hello from Sup!" (works via copied property)

// Now add a new method to the parent prototype
Sup.prototype.sayHi = function() { console.log('Hi from Sup!'); };

sub1.sayHi(); // Output: "Hi from Sup!" (inherited via prototype chain)
sub2.sayHi(); // Error: sub2.sayHi is not a function (no link to parent prototype)

// Check instanceof
console.log(sub1 instanceof Sup); // true (correct prototype chain)
console.log(sub2 instanceof Sup); // false (no chain connection)

// Access non-enumerable property
console.log(sub1.secretProp); // "I am hidden" (accessible via prototype chain)
console.log(sub2.secretProp); // undefined (not copied by Object.assign)

Summary

Object.create(Sup.prototype) is the right choice because it implements the actual prototype chain that defines JavaScript’s inheritance model. It maintains a dynamic link between child and parent prototypes, preserving all the expected inheritance behaviors. Object.assign only creates a static copy of properties, breaking the prototype chain and losing key inheritance features.

内容的提问来源于stack exchange,提问作者karthikaruna

火山引擎 最新活动