Understanding the Difference Between Object.Create() and New Somefunction()

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

The object used in Object.create actually forms the prototype of the new object, where as in the new Function() form the declared properties/functions do not form the prototype.

Yes, Object.create builds an object that inherits directly from the one passed as its first argument.

With constructor functions, the newly created object inherits from the constructor's prototype, e.g.:

var o = new SomeConstructor();

In the above example, o inherits directly from SomeConstructor.prototype.

There's a difference here, with Object.create you can create an object that doesn't inherit from anything, Object.create(null);, on the other hand, if you set SomeConstructor.prototype = null; the newly created object will inherit from Object.prototype.

You cannot create closures with the Object.create syntax as you would with the functional syntax. This is logical given the lexical (vs block) type scope of JavaScript.

Well, you can create closures, e.g. using property descriptors argument:

var o = Object.create({inherited: 1}, {
foo: {
get: (function () { // a closure
var closured = 'foo';
return function () {
return closured+'bar';
};
})()
}
});

o.foo; // "foobar"

Note that I'm talking about the ECMAScript 5th Edition Object.create method, not the Crockford's shim.

The method is starting to be natively implemented on latest browsers, check this compatibility table.

What is the real difference between new vs Object.create()

  1. new can be used only with a function or a class.
    When a function is executed as new User(...), it does the following steps:

    • A new empty object is created and assigned to this.

    • The function body executes. Usually it modifies this, adds new properties to it.

    • If there is no explicit return statement, the value of this is returned.



  1. b1obj.key1 is undefined because Object.create first parameter is an object wich becomes a prototype of created object. In this case it is the a1 function, which doesn't have a key1 property assigned, it only assignes key1 to its this when called.


  1. b2obj has the a2 object as its prototype, so it has access to its key2 property

Suming up: while new keyword is more often used to create new instances of objects from an existing 'template', Object.create is more flexible and allows you to work with a prototype, create property descriptors. For example, you can create a shallow copy of object:

let clone = Object.create(Object.getPrototypeOf(obj), 
Object.getOwnPropertyDescriptors(obj));

I suggest you to read this article about new keyword and this one about Object.create and other prototype methods.

UPDATE (about the relationship between object and its prototype):
Once you have created a new object, changing its properties does not affect the prototype. For example,

let a2 = {
key2: "some text"
};
let b2 = Object.create(a2);
a2.key2 = "I am a2";
b2.key2 = "I am b2";

alert(a2.key2 + ", " + b2.key2);

will alert I am a2, I am b2. That's because b2 has its own key2 property. But If it doesn't, JavaScript will look for it in its prototype. You can find a detailed description of the prototype inheritance here

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

The object used in Object.create actually forms the prototype of the new object, where as in the new Function() form the declared properties/functions do not form the prototype.

Yes, Object.create builds an object that inherits directly from the one passed as its first argument.

With constructor functions, the newly created object inherits from the constructor's prototype, e.g.:

var o = new SomeConstructor();

In the above example, o inherits directly from SomeConstructor.prototype.

There's a difference here, with Object.create you can create an object that doesn't inherit from anything, Object.create(null);, on the other hand, if you set SomeConstructor.prototype = null; the newly created object will inherit from Object.prototype.

You cannot create closures with the Object.create syntax as you would with the functional syntax. This is logical given the lexical (vs block) type scope of JavaScript.

Well, you can create closures, e.g. using property descriptors argument:

var o = Object.create({inherited: 1}, {
foo: {
get: (function () { // a closure
var closured = 'foo';
return function () {
return closured+'bar';
};
})()
}
});

o.foo; // "foobar"

Note that I'm talking about the ECMAScript 5th Edition Object.create method, not the Crockford's shim.

The method is starting to be natively implemented on latest browsers, check this compatibility table.

JavaScript inheritance: Object.create vs new

In your question you have mentioned that Both examples seem to do the same thing, It's not true at all, because

Your first example

function SomeBaseClass(){...}
SomeBaseClass.prototype = {
doThis : function(){...},
doThat : function(){...}
}
function MyClass(){...}
MyClass.prototype = Object.create(SomeBaseClass.prototype);

In this example, you are just inheriting SomeBaseClass' prototype but what if you have a property in your SomeBaseClass like

function SomeBaseClass(){ 
this.publicProperty='SomeValue';
}

and if you use it like

var obj=new MyClass();
console.log(obj.publicProperty); // undefined
​console.log(obj);​

The obj object won't have publicProperty property like in this example.

Your second example

MyClass.prototype = new SomeBaseClass();

It's executing the constructor function, making an instance of SomeBaseClass and inheriting the whole SomeBaseClass object. So, if you use

    var obj=new MyClass();
console.log(obj.publicProperty); // SomeValue
console.log(obj);​

In this case its publicProperty property is also available to the obj object like in this example.

Since the Object.create is not available in some old browsers, in that case you can use

if(!Object.create)
{
Object.create=function(o){
function F(){}
F.prototype=o;
return new F();
}
}

Above code just adds Object.create function if it's not available so you can use Object.create function and I think the code above describes what Object.create actually does. Hope it'll help in some way.

Difference between: new ExampleConstructor and Object.create(ExampleConstructor)

getWeight doesn't exist on the prototype. It is created on the object itself when the constructor function is run (which isn't happening when you use Object.create instead of calling the function).

Is there any reason to use Object.create() or new in JavaScript?

So far, if you want to create an object, you can only use literals:

var obj = {};

or the Object constructor.

var obj = Object();

But none of these methods let you specify the prototype of the created object.

This is what you can do with Object.create now. It lets you create a new object and sets the first argument as prototype of the new object. In addition, it allows you to set properties of the new object provided as second argument.

It is similar to doing something like this (without the second argument):

function create(proto) {
var Constr = function(){};
Constr.prototype = proto;
return new Constr();
}

So if you are using a construct similar to this, this when you wanted to use Object.create.

It is not a replacement for new. It is more an addition to make creating single objects which should inherit from another object simpler.

Example:

I have an object a:

var a = {
someFunction: function() {}
};

and I want b to extend this object. Then you can use Object.create:

b = Object.create(a);
b.someOtherFunction = function(){};

Whenever you have a constructor function, but you only instantiate one object from it, you might be able to replace this with Object.create.

There is general rule that applies. It depends very much on what the constructor function is doing and how you inherit from other objects, etc.



Related Topics



Leave a reply



Submit