What is the difference between Object.create or new Object() in Javascript?

Asked

Viewed 570 times

22

I’m going through a technical doubt in Javascript:

  • What’s the difference between Object.create and new Object()?
  • What cases do I have to adopt one over the other?

2 answers

6


The method Object.create receive parameters. The first is required and will be used as prototype of the new object. The second is a map of properties with which object is already "born".

Already new Object() is a longer and not recommended way of saying {}.

The three lines of code below are equivalent:

let a = {}; // legal
let b = new Object(); // coisa de dinossauros pedantes

let c = Object.create(null); // isso pode ser útil se ao invés de nulo
                             //você passar um parâmetro.

The method create can be quite useful if you use some more complex logic to create your objects. Again, the two snippets of code below are equivalent:

// forma verbosa
let foo = {};
foo.prototype = Array;

let bar = {nome: "john", idade: 21};

for (let propriedade in bar) {
    foo[propriedade] = bar[propriedade];
}

// forma curta
let foo = Object.create(Array, {nome: "john", idade: 21});
  • 6

    Wow, I use new Object().... I felt offended :p.

  • 2

    Pedant dinosaur coia was great. foo.prototype = Array You have no right to appeal, you go straight to the gallows. I don’t have time to elaborate a response, but there are some particularities of each method, for example, with Object.create you can "inherit" the properties of an object without inheriting its prototype, as well as do a number of interesting things (e. g., mixin). For more details: MDN - Object.create().

  • 2
  • 3

    Hi! Your answer is with several incorrect and/or inaccurate details. I will highlight them here: 1) The second argument of Object.assign nay serves to "define the properties with which object is already born", but rather defines the property descriptors initials. 2) Object.assign(null) is not the same as {} or new Object (as the first example of code incorrectly suggests). 3) The second example of code is incorrect, since the property prototype nay defines a prototype, but it is a special property of builders that will be assigned to the prototype [...]

  • 3

    object during instantiation. Use the (not recommended) property __proto__ for that or methods such as Reflect.setPrototypeOf or Object.setPrototypeOf to do so. Furthermore, as I said earlier, the second argument of Object.assign does not define initial properties, but rather initial property descriptors, so that makes this incorrect: Object.create(Array, {nome: "john", idade: 21}). I tried to detail a little more in the reply I wrote.

6

TL;DR

In the great majority sometimes, to create an object in Javascript, just do something like this:

const myObject = {
  // ...
};

So, a new object will have been created myObject whose prototype points to Object.prototype. The {} (literal form), is analogous to use new Object() or Object(). Despite this equivalence, always use {}.

Already the function Object.create, differently demonstrated above, shall be used when:

  • It is necessary to define a prototype different from the object to be created; and/or:
  • It is necessary to define property descriptors initials of the object to be created (not to be confused with properties).

Therefore, when creating an object with {}, new Object() or Object(), is limited to a new object whose prototype is always Object.prototype. The function Object.create allows the creation of objects with a different prototype and/or properties with defined descriptors with higher granularity.


First argument from Object.create

The first argument of Object.create is useful to define a "custom prototype" in the creation of an object. So, in the example below:

const customPrototype = {}; // Qualquer objeto.

const obj = Object.create(customPrototype);

The object obj will prototype the object customPrototype, which was passed in the first argument of the function. Then the evaluation of Reflect.getPrototypeOf(obj) === customPrototype would result in true.

It’s kind of the same as this:

const customPrototype = {}; // Qualquer objeto.

const obj = {};
Reflect.setPrototypeOf(obj, customPrototype);

The disadvantage of redefining the prototype after the object has been created is that the actuasi Javascript interpreters do not have optimizations for the prototypical reset, since it is an unusual and relatively costly operation (the entire prototyping chain of the object will be changed). Therefore, it is more appropriate to define the customized prototype during the creating of the object than to do this once the object has already been created. Therefore there is the first argument of Object.create.

Second argument from Object.create

The second argument from Object.create defines the property descriptors that the object to be created will possess.

Contrary to the many people think, the second argument of Object.create does not serve to define initial properties for an object, but rather to define the property descriptors initials that the object will take over. About property descriptors and attributes, it is an extensive subject that gives an answer by itself. I deal in more detail about them in What and how Javascript property descriptors and attributes work?.

So an example (creating a new object whose prototype is null and with the property descriptors):

const obj = Object.create(null, {
  name: {
    value: 'Bob',
    writable: false,
    enumerable: false,
    configurable: false
  },
  age: {
    value: 50,
    writable: false,
    enumerable: false,
    configurable: false
  }
});

console.log(obj);
console.log(Object.keys(obj));

console.log('---\nAs propriedades estão aqui!');

// As propriedades estão lá! Só não podem ser enumeradas
// normalmente porque o atributo `enumerable` de cada
// propriedade foi definido, na criação, como `false`.
console.log(Object.getOwnPropertyNames(obj));
console.log(obj.name);
console.log(obj.age);

So it’s not right to do this:

// Este código não é válido.
const obj = Object.create(null, {
  name: 'Bob',
  age: 50
});

As the second argument does not contain descriptor(s) of property valid(s), the following error will be launched:

Uncaught TypeError: Property description must be an object

It is less intuitive and less useful. It would be much more interesting to use the second argument of Object.create to define the estates (not to be confused with property descriptor) to be assumed by the object during its creation. If necessary, one can combine Object.create with Object.assign:

// Criaremos um objeto cujo protótipo é `null`
// E as propriedades definidas inicialmente são `name` e `age`:
const obj = Object.assign(Object.create(null), {
  name: 'Bob',
  age: 50
});

console.log(obj); //=> { name: "Bob", age: 50 }
console.log(Reflect.getPrototypeOf(obj)); //=> null

More details about the Object.assign in this answer or in the documentation.

As a matter of curiosity, in addition to Object.create, the functions Object.defineProperty and Object.defineProperties can also be used to define properties by describing properties on an object. The difference is that Object.create makes in creation and, the last two, once the object has been created.

Considerations on {}, Object() and new Object()

Are equivalent:

1 | const a = {};
2 | const b = new Object();
3 | const c = Object();

In line 1, an object is created from the literal notation. In line 2, an object is created from the instantiation of the constructor Object. In line 3, an object is created from the invocation of Object. All three will create a new object whose prototype is Object.prototype.

Demonstration:

const a = {};
const b = new Object();
const c = Object();

console.log(Reflect.getPrototypeOf(a) === Object.prototype); //=> true
console.log(Reflect.getPrototypeOf(b) === Object.prototype); //=> true
console.log(Reflect.getPrototypeOf(c) === Object.prototype); //=> true

So, nay it is correct to say that the above three forms are equivalent to Object.create(null), since the prototypes are different.

When using Object.create(null), creates a new object in which null is the prototype. Already use {}, Object() or new Object() are three forms equivalents to create a new object in which Object.prototype is the prototype.

However, Object.create(Object.prototype) is, yes, equivalent to the three forms in question.


They are subtle details, but they make a difference. This another excellent answer gives more details on the prototyping chain, which is a fundamental concept to understand this answer about Object.create.

In addition, the reading on property descriptors is also important to fully understand the functioning of Object.create.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.