Monday, January 25, 2016

Prototype Inheritance: Functions vs objects and Object.create() vs new

Tuesday, February 2nd 2016

The issue:
http://jsbin.com/miweje/edit?js,console

The link is meant to demonstrate the different behavior of Object.create with functions vs. objects. Native properties can be accessed with Object.create for objects, but NOT for functions. So in regards to the challenges, I thought that the Object.create was a method used on functions, not realizing that they are also used on objects. So, if in the challenges, obj1 and obj2 were functions, (not objects - though functions are objects....yeah) then the Object.create would make it so that obj2 would NOT be able to access obj1.x. However, because they WERE objects, obj2 had access to obj1 via the prototype chain. So...why? Prototype inheritance of course!

Object.create()

"The Object.create() method creates a new object with the specified prototype object and properties."

Object.create() creates a new object with the prototype object and properties. The keyword here is prototype object. Why does this matter? Well lets check this out:

var obj1 = {x:10};
var obj2 = Object.create(obj1);
console.log(obj2.x);      //10;
console.log(Object.keys);    // []

Object.create extends obj2's prototype chain, such that when we call on obj2.x, it is forced to look up the prototype chain because x is not a native property of obj2. But check this out:


var bird = Object.create(Animal);
bird.prototype = Object.create(Animal.prototype);
console.log(bird.x);  //undefined

What?? That's crazy! Well, not really. When we look at what the prototype object is, we can actually see it references the Animal function as a whole:
function() { this.x = 10; };

Because its referencing a function rather than a specific set of properties, our bird variable does not have access to the x property. It does, however, have access to that constructor function.

new

var obj1 = {x:10};
var obj2 = new obj1;  //error!

An error? What, why? Because obj1 is not a function.

"The new operator creates an instance of a user-defined object type or of one of the built-in object types that has a constructor function."

We cannot use the new keyword to extend the prototype object of objects. They can only (reasonably) be used on function objects. Whereas, if we use it correctly:

var Animal = function () { x:10 };
var bird = new Animal();
console.log(Object.keys(bird));  //['x'];

The new keyword invokes the constructor function, thereby creating another object that has access to the constructor function's native properties. It doesn't have to look in the prototype chain. Therefor, bird has its own 'this.x' property that is equal to '10'.

The main difference between Object.create() and new in regards to functions is that Object.create() doesn't fire the constructor. With Object.create, you have the option of firing the object constructor that forms the prototype of the new object, where as in the new Function() form, the declared properties/functions do not form the prototype.

It's as Johnathan Kvicky, mentor, said, ""Very simply said, new X is Object.create(X.prototype) with additionally running the constructor function. (And giving the constructor the chance to return the actual object that should be the result of the expression instead of this)".

References:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain
http://javascript.info/tutorial/inheritance
http://www.htmlgoodies.com/html5/tutorials/javascript-prototypical-inheritance-explained.html#fbid=WDOO4VJLwnp

No comments:

Post a Comment