Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does object.create work in JavaScript?

Tell me if I'm wrong:

A prototype is a normal object. When an object inherits a prototype, it does not just copy the properties of the prototype, the object stores a reference to the prototype.

In Firefox, I can do:

var food = {fruit:"apple"};
var more_food = {vegetable:"celery"};
food.__proto__ = more_food;
food.vegetable // celery
food.fruit // apple

I can use the __proto__ property to manually set the reference to the prototype object.

I can also use Object.create:

var food = {fruit:"apple"};
var more_food = {vegetable:"celery"};
food = Object.create(more_food);
food.vegetable // celery
food.fruit // undefined

What exactly is Object.create doing? Is the variable food assigned the reference to the prototype more_food, or is Object.create just returning a copy of the object more_food? If Object.create is just making a copy, then how does the prototype chain work if the variable food has no reference to more_food?

like image 731
Brian Avatar asked Nov 01 '11 05:11

Brian


People also ask

How is object created in JavaScript?

Creating a JavaScript Object Create a single object, using an object literal. Create a single object, with the keyword new . Define an object constructor, and then create objects of the constructed type. Create an object using Object.create() .

How does object work in JavaScript?

JavaScript is designed on a simple object-based paradigm. An object is a collection of properties, and a property is an association between a name (or key) and a value. A property's value can be a function, in which case the property is known as a method.

Why do we use object create in JavaScript?

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.

What is object Create method?

The Object. create() method creates a new object, using an existing object as the prototype of the newly created object.


1 Answers

A prototype is a normal object. When an object inherits a prototype, it does not just copy the properties of the prototype, the object stores a reference to the prototype.

You're right, the prototype of an object, is just another object referenced through the prototype chain.

The difference between your two snippets is that with __proto__ you are mutating the prototype of food. In your second example, you are just assigning a new object that inherits from more_food, that's why food.fruit is resolved to undefined, because your original food object is lost by that assignment.

What exactly is Object.create doing?

Object.create builds a new object that inherits from the object passed as its first argument (it can be only either an object or null).

Is the variable food assigned the reference to the prototype more_food, or is Object.create just returning a copy of the object more_food?

Your food variable will hold a new object, which inherits from more_food, there's no any copying in this operation.

For example:

var food = {fruit:"apple"};
var more_food = Object.create(food, {
  vegetable: { value: "celery" }
});

more_food.fruit;     // "apple"
more_food.vegetable; // "celery"

In the above example, more_food inherits from food, in other words, food is the prototype of more_food, this prototypical reference is stored in an internal property called [[Prototype]]. The second argument of Object.create allows you to initialize properties on this new object.

There's no copying, it's just plain delegation in the above example more_food.fruit is accesible through the prototype chain, the property lookup process is really simple, if a property is not found on an object, it's looked up again (delegation!) on the object's prototype, recursively, until an object whose prototype is null is found (like Object.prototype).

So, more_food.fruit is an inherited property:

more_food.hasOwnProperty('fruit'); // false, inherited
'fruit' in more_food;              // true

While vegetable is an own property of more_food:

more_food.hasOwnProperty('vegetable'); // true

The above example looks graphically like this:


  +---------------------+  [[Prototype]]  +---------------+
  | more_food           |+--------------->| food          |
  |---------------------|                 |---------------|
  | vegetable: "celery" |                 | fruit: "apple |
  +---------------------+                 +---------------+

If Object.create is just making a copy, then how does the prototype chain work if the variable food has no reference to more_food?

Object.create doesn't create copies of objects, it just sets up the prototype of a new object at the time of its creation.

Keep in mind that __proto__ is a non-standard feature and it's going to be removed from implementations in the future, is already being listed as deprecated on the Mozilla Documentation, the main reason of this, and it's also why the language may never have a way to mutate the prototype chain in the way __proto__ allows you is that it causes optimization and security problems, at the level of VM and JIT.

like image 170
Christian C. Salvadó Avatar answered Sep 18 '22 04:09

Christian C. Salvadó