Explain Codes LogoExplain Codes Logo

Understanding the difference between Object.create() and new SomeFunction()

javascript
object-oriented-programming
prototype-inheritance
javascript-features
Nikita BarsukovbyNikita Barsukov·Sep 8, 2024
TLDR

While Object.create(proto) provides direct control over the created object's prototype and does not invoke a constructor, new Constructor() creates an object by executing the Constructor function, which assigns properties and methods, plus automatically links the object's prototype to Constructor.prototype.

Example:

Object.create():

const proto = { chat: () => 'Hola!' }; // Inherited from Uncle Prototype const obj = Object.create(proto); // Inherits 'chat' method console.log(obj.chat()); // Outputs: 'Hola!'

new Constructor():

function Chatter() { this.chat = () => 'Ciao!'; // Constructing in Italian } const obj = new Chatter(); // Constructs a new "Chatter" console.log(obj.chat()); // Outputs: 'Ciao!'

In Object.create(): the genes (properties and methods) are replicated from a prototypal pool, whereas new brings objects into existence using a constructor function as a template.

When it makes sense: Choosing "new" or "Object.create()"

new SomeFunction() is your builder, perfect for when constructor logic needs to run - like setting up initial state or binding methods. On the other hand, Object.create() gives you the blueprints to set inheritance chains without potential constructor side-effects.

Object.create(null) offers a clean start to create an object devoid of inherited properties. On the new SomeFunction() side of the world, you would need to turn SomeFunction.prototype to null, which isn't as straightforward.

You're looking at property descriptors and keen on setting up closures? Again, Object.create() steps up providing deeper control compared to the automatic setup with new SomeFunction().

Footloose with Object.create(): Exploring non-constructor creation

Object.create() enables creation of an object prototype directly from another object, eliminating unexpected constructor side-effects. It even lets you create a closure within an object — that's like hiding your precious diary (private variables) in the object.

Such differentiation is crucial with ECMAScript 5 features, that introduced Object.create() for flexible, prototype-based inheritance as a step-up on new's single, constructor-bound prototype chain.

Inheritance vs Instance: Distinguishing the object creation goals

Need a brand-new instance like a shiny new toy with your own setup? Go for new SomeFunction(). But if you need an object tied with a specific prototype lineage or a totally empty object, Object.create() is your warhorse.

From inheritance controls with Object.create() to constructor-defined instantiation with new SomeFunction(), your best pick lies in how well your method can tie your code's architecture to your application design intentions.

Real-world use cases and code snippets

Frameworks like Vue.js employ Object.create() for prototype injection, allowing shared methods without each redefining them. Conversely, React.js loves new to instantiate new instances where component initialization and state setup are vital.

Let's return to code for a while. Create an empty object with Object.create(null) to prevent unforeseen mishaps from inherited properties when crafting 'pure' dictionaries or maps:

let map = Object.create(null); map['123'] = 'test'; console.log( map['123'] ); // test console.log( map.hasOwnProperty('123') ) // Error: map.hasOwnProperty is not a function. // No overhead from the prototype!

On the other side, new is your best friend for constructing ORM models or service objects on Node.js backends, capitalizing on constructor functions:

class Database { constructor(url) { this.url = url; // constructor defines the initial state. } } const db = new Database('mongodb://localhost:27017'); console.log(db.url); // mongodb://localhost:27017

Consider browser support and compatibility

Given that Object.create() was introduced in ECMAScript 5, being aware of its compatibility across diverse JavaScript environments is key. Though widely supported today, older environments might necessitate polyfills. However, new has been a JavaScript buddy since the very beginning.

Advanced tools for object-oriented JavaScript

To build complex inheritance patterns, mastering more advanced tools like Object.setPrototypeOf() — or even better, using Object.create() — is paramount. It allows crafting multiple layers of inheritance, carrying similar functionalities from class-based OO languages, keeping the flexibility intact.