227

What is the difference between this constructor-based syntax for creating an object:

person = new Object()

...and this literal syntax:

person = {
    property1 : "Hello"
};

It appears that both do the same thing, although JSLint prefers you use object literal notation.

Which one is better and why?

apsillers
  • 112,806
  • 17
  • 235
  • 239
ectype
  • 14,865
  • 5
  • 21
  • 28
  • 7
    All the same: `a = new Object`, `a = new Object()`, `a = {}`, literal is much simpler and some tests I ran a while ago say it is faster, newer compilers may have caused my statement to be false. Same applies to literal arrays – Ruan Mendes Jan 04 '11 at 20:55
  • 9
    Hopefully you are declaring your variables with the `var` keyword in your application code to avoid polluting the global namespace and creating the need to look beyond the current record in the stack for your variables. – Samo Jan 04 '11 at 21:40
  • @Samo hey man, good tip. But what do you mean by "the current record in the stack"? If I'm missing something I'd like to learn it – Chris Bier Oct 20 '14 at 21:37
  • 1
    Basically, at any point during the execution of a program, there is a stack of records or blocks. Each record has a list of variables that were created in that scope. In JavaScript, if an expression contains a variable and the interpreter can't find it in the stack record for that scope, it will keep going up to the next record until it finds the variable. More info http://davidshariff.com/blog/what-is-the-execution-context-in-javascript/ – Samo Oct 22 '14 at 16:56
  • 2
    Avoiding JSLint's is the first step in becoming a good developer. Using `new` is a convention that transcends the pointless nitpicking of a mediocre language. Use `new` because its meaning is clear. In 99.9% of the case, the performance gains are irrelevant. – Hal50000 Feb 23 '16 at 17:18
  • 1
    @Hal50000 mediocre language according to whom? – Xam Jan 09 '19 at 20:53

12 Answers12

250

There is no difference for a simple object without methods as in your example. However, there is a big difference when you start adding methods to your object.

Literal way:

function Obj( prop ) { 
    return { 
        p : prop, 
        sayHello : function(){ alert(this.p); }, 
    }; 
} 

Prototype way:

function Obj( prop ) { 
    this.p = prop; 
} 
Obj.prototype.sayHello = function(){alert(this.p);}; 

Both ways allow creation of instances of Obj like this:

var foo = new Obj( "hello" ); 

However, with the literal way, you carry a copy of the sayHello method within each instance of your objects. Whereas, with the prototype way, the method is defined in the object prototype and shared between all object instances. If you have a lot of objects or a lot of methods, the literal way can lead to quite big memory waste.

basickarl
  • 37,187
  • 64
  • 214
  • 335
Rémy DAVID
  • 4,343
  • 6
  • 25
  • 27
  • 56
    To me the question was more about the differences between using `new Object()` vs `{}` to create empty objects. – Peter Oct 10 '14 at 00:42
  • And that's what this answers. – Lobabob Oct 10 '14 at 01:23
  • 11
    @Lobabob Aside from the first sentence, this answer doesn't actually provide any information about OP's question. It doesn't even contain 'new Object()` anywhere. Frankly, I think Mr. David misunderstood the question. – JLRishe Dec 29 '14 at 15:08
  • 27
    When I posted this the accepted answer was already there and accepted. And it perfectly answers the OP question so I was not going to repeat the same thing. I posted my answer mainly to broaden the subject beyond empty/simple objects. In which case there *is* an important difference which is worth mentioning. – Rémy DAVID Dec 29 '14 at 16:46
  • 6
    This answer is off-topic. In your code, Obj is a separate class inheriting from Object. When you use object literal notation, you use Object class, not Obj. Of course setting up a class with method in its prototype is going to make memory footprint smaller than creating a lot of plain Objects and adding method as their properties, but that's completely unrelated to the question asked here. The correct answer to this question is "no, there is absolutely no difference (maybe except the readability)". – dos May 21 '15 at 00:40
  • 1
    Although the entry is quite old: The 'literal' way creates an object but returns as well a closure whie in your Protoype way it runs simply the function. So, I doubt the samples are really comparable.. – LeO Jul 14 '15 at 14:19
  • 3
    This has literally NOTHING to do with the question, and can only cause confusion because of that. Putting a property on the prototype is a completely different thing than putting a property on the object itself...and that applies whether the property you're making is a function or not. You're making this out like this is some "method vs non-function property" thing, when in reality functions and non-function values can be assigned equally to the actual object or the object's prototype, and either way assigning it to the prototype has nothing to do with this question. – Jimbo Jonny Jan 09 '16 at 22:03
  • 2
    ^the tl;dr version of that is that this answer is basically saying "It's different if you do something totally different." – Jimbo Jonny Jan 09 '16 at 22:42
  • 4
    I came for this answer, based on a question that was kind of like mine, but ended up learning exactly what I needed to know. Thank you. – Pat Migliaccio Jul 22 '16 at 17:17
  • If you use an IIFE which returns a function, you can use the "private scope" trick to only declare the function once, yet allow it to be a member of every instance of the constructor function. – 4castle Aug 02 '16 at 05:39
  • Well copying a function around is wasteful, however you could define a "global" function `sayHello(obj)` and do `sayHello(foo)` instead of `foo.sayHello()`. – Rolf Mar 20 '18 at 12:34
  • This answer is confusing. I would suggest at least naming the constructor in the answer not `Obj` but something else. – Koray Tugay Sep 26 '21 at 17:05
  • 1
    this point was made in a very informative video course i recently watched called [Javascript: Understanding the Weird Parts](https://www.youtube.com/watch?v=Bv_5Zv5c-Ts). i didn’t fully understand it at the time, but coming across this point again, in a different format, makes it a lot clearer and emphasises how important it is to understand and remember. – user1063287 Nov 19 '21 at 14:44
  • 1
    I am so happy that I learned something new from this answer. I've never realized that the literal way might cause unnecessary memory consumption! Just because it didn't directly answer the OP, it doesn't mean it's a bad answer, and it's closely related to the OP anyway. – Zhou Dec 02 '21 at 13:38
134

They both do the same thing (unless someone's done something unusual), other than that your second one creates an object and adds a property to it. But literal notation takes less space in the source code. It's clearly recognizable as to what is happening, so using new Object(), you are really just typing more and (in theory, if not optimized out by the JavaScript engine) doing an unnecessary function call.

These

person = new Object() /*You should put a semicolon here too.  
It's not required, but it is good practice.*/ 
-or-

person = {
    property1 : "Hello"
};

technically do not do the same thing. The first just creates an object. The second creates one and assigns a property. For the first one to be the same you then need a second step to create and assign the property.

The "something unusual" that someone could do would be to shadow or assign to the default Object global:

// Don't do this
Object = 23;

In that highly-unusual case, new Object will fail but {} will work.

In practice, there's never a reason to use new Object rather than {} (unless you've done that very unusual thing).

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
kemiller2002
  • 113,795
  • 27
  • 197
  • 251
  • 13
    The author chose this answer as correct, but it is incomplete. Be aware there are differences between the two syntaxes when you get into memory allocation. – newshorts May 20 '15 at 00:29
  • 2
    There are no differences. If you're referring to one of the answers under, it's off-topic, as it's talking about prototype-based object model and inheritance (the code there setups a Obj class that inherits from plain Object). This question isn't about creating an instance of some custom class - it's about creating instance of Object, and the correct answer to this question is "there is no difference". – dos May 21 '15 at 00:44
  • FYI also `()` `new Object()` is not required. ( talking about not required thingy) – Royi Namir Jun 10 '15 at 06:50
  • I think we need not use **new** as of the current specification. Let me know your thoughts @kevin – Vamsi Pavan Mahesh Jun 12 '15 at 08:10
  • @newshorts: *" there are differences between the two syntaxes when you get into memory allocation"* No, there aren't. – T.J. Crowder Feb 03 '16 at 11:05
  • @VamsiPavanMahesh: Yes, `new Object` and `Object()` (calling it with no arguments) do the same thing, as far back as the 3rd edition spec in 1999 (I didn't try to find an older one). – T.J. Crowder Feb 03 '16 at 11:13
  • I the SECOND case the semi-colon isn't required. Javascript is drowning in parenthesis, brackets and semi-colons; – Hal50000 Feb 23 '16 at 17:20
  • Your last sentence doesn't make sense. – Melab Jun 27 '19 at 03:00
  • 1
    You can also use Object create and pass null if you want an object that doesn't inherit from the inheritance chain. They are not equal and have useful purposes respectively. – Aaron Jul 21 '19 at 12:52
59

In JavaScript, we can declare a new empty object in two ways:

var obj1 = new Object();  
var obj2 = {};  

I have found nothing to suggest that there is any significant difference these two with regard to how they operate behind the scenes (please correct me if i am wrong – I would love to know). However, the second method (using the object literal notation) offers a few advantages.

  1. It is shorter (10 characters to be precise)
  2. It is easier, and more structured to create objects on the fly
  3. It doesn’t matter if some buffoon has inadvertently overridden Object

Consider a new object that contains the members Name and TelNo. Using the new Object() convention, we can create it like this:

var obj1 = new Object();  
obj1.Name = "A Person";  
obj1.TelNo = "12345"; 

The Expando Properties feature of JavaScript allows us to create new members this way on the fly, and we achieve what were intending. However, this way isn’t very structured or encapsulated. What if we wanted to specify the members upon creation, without having to rely on expando properties and assignment post-creation?

This is where the object literal notation can help:

var obj1 = {Name:"A Person",TelNo="12345"};  

Here we have achieved the same effect in one line of code and significantly fewer characters.

A further discussion the object construction methods above can be found at: JavaScript and Object Oriented Programming (OOP).

And finally, what of the idiot who overrode Object? Did you think it wasn’t possible? Well, this JSFiddle proves otherwise. Using the object literal notation prevents us from falling foul of this buffoonery.

(From http://www.jameswiseman.com/blog/2011/01/19/jslint-messages-use-the-object-literal-notation/)

user1063287
  • 10,265
  • 25
  • 122
  • 218
James Wiseman
  • 29,946
  • 17
  • 95
  • 158
  • 1
    How about Object.Create? See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FObject%2Fcreate – Phil Mar 07 '14 at 00:11
  • If you're going to favor object literals over `new Object()` because of the possibility that something overwrote the Object function, you should also be writing guards all over the place when you use helpers like `Object.keys` to make sure it's not undefined, which descends into absurdity. I would always recommend people use the literal notation, but I think this particular argument falls apart when you think of the consequences of thinking that way. – philraj Feb 04 '18 at 21:49
  • 1
    SyntaxError: Unexpected token '='. Expected a ':' following the property name 'TelNo'. – Benoît P Mar 03 '21 at 18:11
45

On my machine using Node.js, I ran the following:

console.log('Testing Array:');
console.time('using[]');
for(var i=0; i<200000000; i++){var arr = []};
console.timeEnd('using[]');

console.time('using new');
for(var i=0; i<200000000; i++){var arr = new Array};
console.timeEnd('using new');

console.log('Testing Object:');

console.time('using{}');
for(var i=0; i<200000000; i++){var obj = {}};
console.timeEnd('using{}');

console.time('using new');
for(var i=0; i<200000000; i++){var obj = new Object};
console.timeEnd('using new');

Note, this is an extension of what is found here: Why is arr = [] faster than arr = new Array?

my output was the following:

Testing Array:
using[]: 1091ms
using new: 2286ms
Testing Object:
using{}: 870ms
using new: 5637ms

so clearly {} and [] are faster than using new for creating empty objects/arrays.

Community
  • 1
  • 1
rjloura
  • 554
  • 4
  • 6
  • 3
    I feel like this is the answer that the question was really looking for, though I would like to have seen this additionally tested on an object with a few properties to make sure. – Chase Sandmann Jul 16 '14 at 16:12
  • 2
    Interesting numbers. There are people who need to be aware of this, but I take away that allocating even a meager 200,000 objects is only gonna cost me 5.6ms, so I'm not gonna worry about it. –  Jul 23 '15 at 16:10
  • On Node 10.13.0 things HAVE CHANGED Testing Array: using[]: 117.178ms using new: 116.947ms Testing Object: using{}: 116.252ms using new: 115.910ms – PirateApp Apr 13 '19 at 15:34
  • On `node v16.16.0`, both `{}` and `new` are giving me very similar results; Testing Array: using[]: 154.437ms | using new: 142.843ms --- Testing Object: using{}: 142.678ms | using new: 142.17ms – fujy Oct 27 '22 at 12:24
34

Everyone here is talking about the similarities of the two. I am gonna point out the differences.

  1. Using new Object() allows you to pass another object. The obvious outcome is that the newly created object will be set to the same reference. Here is a sample code:

    var obj1 = new Object();
    obj1.a = 1;
    var obj2 = new Object(obj1);
    obj2.a // 1
    
  2. The usage is not limited to objects as in OOP objects. Other types could be passed to it too. The function will set the type accordingly. For example if we pass integer 1 to it, an object of type number will be created for us.

    var obj = new Object(1);
    typeof obj // "number"
    
  3. The object created using the above method (new Object(1)) would be converted to object type if a property is added to it.

    var obj = new Object(1);
    typeof obj // "number"
    obj.a = 2;
    typeof obj // "object"
    
  4. If the object is a copy of a child class of object, we could add the property without the type conversion.

    var obj = new Object("foo");
    typeof obj // "object"
    obj === "foo" // true
    obj.a = 1;
    obj === "foo" // true
    obj.a // 1
    var str = "foo";
    str.a = 1;
    str.a // undefined
    
bfavaretto
  • 71,580
  • 16
  • 111
  • 150
Jermin Bazazian
  • 1,932
  • 2
  • 17
  • 20
  • 3
    i'm very confused about the last two lines.. Why if you assign to str.a the value 1, str.a is undefined?.. @Jermin Bazazin – Andrea Scarafoni Sep 09 '14 at 12:51
  • 3
    @AndreaScarafoni because `str` is of type `string` so you cannot assign a property to it. http://jsfiddle.net/grq6hdx7/1/ – Chris Bier Oct 21 '14 at 00:06
  • 1
    Has the answer to 4 changed? I get false, not true, in latest Chrome 53 `var obj = new Object("foo"); typeof obj; obj === "foo" // true` – William Hilton Oct 03 '16 at 17:44
26

Actually, there are several ways to create objects in JavaScript. When you just want to create an object there's no benefit of creating "constructor-based" objects using "new" operator. It's same as creating an object using "object literal" syntax. But "constructor-based" objects created with "new" operator comes to incredible use when you are thinking about "prototypal inheritance". You cannot maintain inheritance chain with objects created with literal syntax. But you can create a constructor function, attach properties and methods to its prototype. Then if you assign this constructor function to any variable using "new" operator, it will return an object which will have access to all of the methods and properties attached with the prototype of that constructor function.

Here is an example of creating an object using constructor function (see code explanation at the bottom):

function Person(firstname, lastname) {
    this.firstname = firstname;
    this.lastname = lastname;
}

Person.prototype.fullname = function() {
    console.log(this.firstname + ' ' + this.lastname);
}

var zubaer = new Person('Zubaer', 'Ahammed');
var john = new Person('John', 'Doe');

zubaer.fullname();
john.fullname();

Now, you can create as many objects as you want by instantiating Person construction function and all of them will inherit fullname() from it.

Note: "this" keyword will refer to an empty object within a constructor function and whenever you create a new object from Person using "new" operator it will automatically return an object containing all of the properties and methods attached with the "this" keyword. And these object will for sure inherit the methods and properties attached with the prototype of the Person constructor function (which is the main advantage of this approach).

By the way, if you wanted to obtain the same functionality with "object literal" syntax, you would have to create fullname() on all of the objects like below:

var zubaer = {
    firstname: 'Zubaer',
    lastname: 'Ahammed',
    fullname: function() {
        console.log(this.firstname + ' ' + this.lastname);
    }
};

var john= {
    firstname: 'John',
    lastname: 'Doe',
    fullname: function() {
        console.log(this.firstname + ' ' + this.lastname);
    }
};

zubaer.fullname();
john.fullname();

At last, if you now ask why should I use constructor function approach instead of object literal approach:

*** Prototypal inheritance allows a simple chain of inheritance which can be immensely useful and powerful.

*** It saves memory by inheriting common methods and properties defined in constructor functions prototype. Otherwise, you would have to copy them over and over again in all of the objects.

I hope this makes sense.

Md. Zubaer Ahammed
  • 931
  • 11
  • 13
  • Thanks! Karl for adding the missing "this" in the object literal. It was a horrible mistake..I shouldn't have make this type of mistake. – Md. Zubaer Ahammed Aug 05 '16 at 04:46
  • "You cannot inherit from an object created with literal syntax." - Not true (I believe). You can use `Object.create()` or `new Object()` and create inheritance chains as needed. – balajeerc Nov 21 '16 at 10:44
  • @balajeerc Thanks for your comment. Actually it should be "You cannot maintain inheritance chain with objects created with literal syntax". Answer's in multiple step: 1. Object.create(): Yes, it's possible to pass an object literal to it and it will return a new object which prototype will that passed object literal. But it doesn't know what's is it's constructor function or don't remember that object literal from which it was created. So, testobj1.constructor will return an empty function and there will be no way to add properties/methods to that object literal as it's parent/ancestor. – Md. Zubaer Ahammed Nov 22 '16 at 14:55
  • @balajeerc 2. new Object(): Almost same thing happens in this case. Moreover, it's worse if you think about memory. Instead of putting the properties and methods to it's prototype, it just copies everything from the passed object literal and puts it into the returned object. It's not good for memory. On the otherhand, I focused on true inheritence chain with a constructor function where you can edit methods and properties on the fly and other objects created using the constructor method are also affected as they are pointing to that constructor function only (instead of copying them). – Md. Zubaer Ahammed Nov 22 '16 at 14:57
  • @balajeerc Example: `function Person(firstname, lastname) { this.firstname = firstname; this.lastname = lastname; } Person.prototype.fullname = function() { console.log(this.firstname + ' ' + this.lastname); } var zubaer = new Person('Zubaer', 'Ahammed'); var john = new Person('John', 'Doe'); zubaer.fullname(); // Zubaer Ahammed john.fullname(); // John Doe zubaer.constructor.prototype.fullname = function() { console.log( 'Hello ' + this.firstname); } zubaer.fullname(); // Hello Zubaer john.fullname(); // Hoello John ` – Md. Zubaer Ahammed Nov 22 '16 at 14:59
  • @balajeerc In the end, Objects created form a constructor function knows from where they are inherited/created. – Md. Zubaer Ahammed Nov 22 '16 at 14:59
  • @Md.ZubaerAhammed when i'm running your code nothing happens, why ? –  Jun 16 '19 at 13:51
  • @user10727653 Just try to copy my example code and paste it into a browser console. Or, can you be more specific about the issue you are facing? – Md. Zubaer Ahammed Mar 17 '22 at 16:10
10

Also, according to some of the O'Really javascript books....(quoted)

Another reason for using literals as opposed to the Object constructor is that there is no scope resolution. Because it’s possible that you have created a local constructor with the same name, the interpreter needs to look up the scope chain from the place you are calling Object() all the way up until it finds the global Object constructor.

adolfo_isassi
  • 229
  • 3
  • 5
4

2019 Update

I ran the same code as @rjloura on my OSX High Sierra 10.13.6 node version 10.13.0 and these are the results

console.log('Testing Array:');
console.time('using[]');
for(var i=0; i<200000000; i++){var arr = []};
console.timeEnd('using[]');

console.time('using new');
for(var i=0; i<200000000; i++){var arr = new Array};
console.timeEnd('using new');

console.log('Testing Object:');

console.time('using{}');
for(var i=0; i<200000000; i++){var obj = {}};
console.timeEnd('using{}');

console.time('using new');
for(var i=0; i<200000000; i++){var obj = new Object};
console.timeEnd('using new');


Testing Array:
using[]: 117.613ms
using new: 117.168ms
Testing Object:
using{}: 117.205ms
using new: 118.644ms
PirateApp
  • 5,433
  • 4
  • 57
  • 90
2

I have found one difference, for ES6/ES2015. You cannot return an object using the shorthand arrow function syntax, unless you surround the object with new Object().

> [1, 2, 3].map(v => {n: v});
[ undefined, undefined, undefined ]
> [1, 2, 3].map(v => new Object({n: v}));
[ { n: 1 }, { n: 2 }, { n: 3 } ]

This is because the compiler is confused by the {} brackets and thinks n: i is a label: statement construct; the semicolon is optional so it doesn't complain about it.

If you add another property to the object it will finally throw an error.

$ node -e "[1, 2, 3].map(v => {n: v, m: v+1});"
[1, 2, 3].map(v => {n: v, m: v+1});
                           ^

SyntaxError: Unexpected token :
  • 4
    You can still use an arrow function, you just need more braces and a return: `[1, 2, 3].map(v => { return {n: v}; });` will net you the same thing... – Heretic Monkey Apr 14 '16 at 17:32
  • Of course you can use regular arrow functions, what I was talking about was the shorthand version, i.e. `param => return_value`, and the difference between using `{}` and `new Object()` in this case. – Andrei Simionescu Apr 15 '16 at 08:20
  • 12
    You can still use the shorthand version AND regular arrow functions. Just wrap the {n: v} with a pair of parentheses: `[1, 2, 3].map(v => ({n: v}));` – Stephen C Jun 08 '17 at 01:38
0

The only time i will use the 'new' keyowrd for object initialization is in inline arrow function:

() => new Object({ key: value})

since the below code is not valid:

() => { key: value} //  instead of () => { return { key: value};}
John Libes
  • 363
  • 3
  • 11
0

There are a lot of great answers here, but I want to come with my 50 cents.

What all of these answers are missing is a simple analogy which would work for a person who just starts his journey in the programming languages.

Hopefully, I will fill this gap with this analogy:

Object Literal Creation vs Constructor-based Syntax

Feel the difference with a sentence creation.

If I have a sentence "I like cheese", I can tell you clearly and loudly (literally, or verbatim): I like cheese.

This is my literal (word by word) creation of the sentence.

All other ways are some tricky ways of making you to understand of what sentence I created exactly. For example, I tell you:

  1. In my sentence, the subject is "I", the object is "cheese", and the predicate is "to like". This is another way of YOU to learn without any ambiguities the very same sentence: "I like cheese".

Or,

  1. My sentence has 3 words: the first one is the n-th word in the English dictionary, the the second one is the m-th word in the English dictionary and the last one is the l-th word in the English dictionary.

In this case, you also come to the same result: you know exactly what the sentence is.

You can devise any other methods which would differ from "word-by-word" sentence creation (LITERAL), and which would be INDIRECT (non literal, non verbatim) method of sentence creation.

I think this is the core concept which lays here.

Andrew Anderson
  • 1,044
  • 3
  • 17
  • 26
-4

Memory usage is different if you create 10 thousand instances. new Object() will only keep only one copy while {} will keep 10 thousand copies.

mgthomas99
  • 5,402
  • 3
  • 19
  • 21