7

This has been answered before, but I wanted to confirm my understanding. In this code:

var somePrototype = {
  speak: function() {
    console.log("I was made with a prototype");
  }
}

function someConstructor() {
  this.speak = function() {
    console.log("I was made with a constructor");
  }
}

var obj1 = Object.create(somePrototype);
var obj2 = new someConstructor();

obj1.speak();
obj2.speak();

They are both fundamentally doing the same thing, correct? The only difference is that the function someConstructor() is hoisted, meaning I can call new instances of it before it is defined, if needed, while the var somePrototype can only be called after it's been defined. Other than that, there's no difference?

8
  • They're doing similar things, but they're quite distinctly different. Commented Apr 8, 2016 at 4:48
  • there are several (maybe subtle) differences, but i can't help but think it's been explained before... Commented Apr 8, 2016 at 4:52
  • @dandavis yes, it's been explained before :) However, the semantics of JavaScript and prototypes are weird and confusing. Commented Apr 8, 2016 at 4:52
  • 1
    @SterlingArcher well it sure is a prototype when it's passed in to Object.create(). Commented Apr 8, 2016 at 4:53
  • 1
    @Pointy—ah, language nuances! If an object is assigned to a function's prototype property, is it a prototype if the function is never used as a constructor? ;-) Commented Apr 8, 2016 at 5:19

2 Answers 2

8

The differences between 2 approaches (using Object.create() and constructor invocation) are:

The creation:

  • Object.create(somePrototype) creates a new object making the somePrototype it's prototype;
  • new someConstructor() creates an object using constructor invocation. The prototype of the obj2 is a simple object: new Object()

The properties inheritance:

  • obj1 inherits the property speak, which is a function. If this property changes in the somePrototype object, this will affect any objects created with Object.create(somePrototype) which inherit it.
    Object.keys(obj1) will return [], because the object has no own properties.
  • obj2 contains an own property speak. Modifying this property on a single instance won't affect any other instances created using new someConstructor().
    Object.keys(obj2) will return ['speak'] as its listed property.

The constructor:

  • obj1.constructor === Object is true
  • obj2.constructor === someConstructor is true

Hoisting:

  • someConstructor is hoisted to the top of scope it was created. So it can be used before the function declaration.
  • And sure somePrototype is not hoisted with the object literal, so should be used after setting up the value.

Check this interesting post about constructor property.

Sign up to request clarification or add additional context in comments.

Comments

6

The Object.create() call creates an object and gives it the prototype you requested. The new call creates an object that's directly decorated by that constructor function.

The difference is that the object created by the constructor has an own property whose value is that function with the console.log(). The Object.create() call creates an object that inherits a similar function from the prototype object.

If you passed the first object to Object.keys(), you wouldn't see the "speak" property; if you passed the second object, you would.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.