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?
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 offood. In your second example, you are just assigning a new object that inherits frommore_food, that's whyfood.fruitis resolved toundefined, because your originalfoodobject is lost by that assignment.Object.createbuilds a new object that inherits from the object passed as its first argument (it can be only either an object ornull).Your
foodvariable will hold a new object, which inherits frommore_food, there's no any copying in this operation.For example:
In the above example,
more_foodinherits fromfood, in other words,foodis the prototype ofmore_food, this prototypical reference is stored in an internal property called[[Prototype]]. The second argument ofObject.createallows you to initialize properties on this new object.There's no copying, it's just plain delegation in the above example
more_food.fruitis 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 isnullis found (likeObject.prototype).So,
more_food.fruitis an inherited property:While
vegetableis an own property ofmore_food:The above example looks graphically like this:
Object.createdoesn'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.