var obj = {};
// obj inherits from something called "Object"
// as a result, it has some special functions!
console.log(obj.hasOwnProperty); // [Function: hasOwnProperty]
console.log(obj.toString()); // [Function: toString]
JavaScript uses inheritance for internal representations. Every object inherits from a base object.
For example, where did these two properties come from? We didn't define them ...
console.log(Object); // [Function: Object]
// ALL objects inherit functionality from Object
// We can see that Object.hasOwnProperty and obj.hasOwnProperty
// point to the same location in memory.
var obj = {};
console.log(Object.hasOwnProperty === obj.hasOwnProperty);
There is a very special object in JavaScript named Object.
The capital O is important.
After the last example, I hope it's clear that you have no choice but to use inheritance.
But there are other good reasons as well:
minionOne = {
sayBanana: function() {
return "banana";
}
};
minionTwo = {
sayBanana: function() {
return "banana";
}
};
// "banana"
minionOne.sayBanana();
// "banana"
minionTwo.sayBanana();
Here, we had to explicitly give each minion a function to "sayBanana".
Whats bad about this?
Object.prototype.sayBanana = function() {
return "banana";
};
{}.sayBanana();
var gollum = {};
gollum.sayBanana();
// Arrays inherit from Object
[].sayBanana();
Here, we give EVERY object the function sayBanana.
Array's inherit from Object, so because we extended Object, we extended Array as well.
Typically, we want something between these two extremes.
var prototypeObject = {
sayBanana: function() {
return "banana";
}
};
var minionOne = Object.create(prototypeObject);
var minionTwo = Object.create(prototypeObject);
console.log(minionTwo.sayBanana());
console.log(minionOne.sayBanana());
[].sayBanana() // throws an error now
This example is a better mix. This time, we give 'minions' a prototype explicitly.
This way we don't have to modify the global Object prototype.
So, what does this tell us about Object.create?
var prototypeObject = {
sayBanana: function() {
return "banana";
}
};
var minionOne = Object.create(prototypeObject);
var minionTwo = Object.create(prototypeObject);
console.log(minionTwo.sayBanana());
console.log(minionOne.sayBanana());
[].sayBanana() // throws an error now
Object.create is a function which returns an object, and takes an object as a parameter.
The object it returns will be an empty object with a prototype of whatever object was passed to Object.create.
function Minion() {
}
Minion.prototype.sayBanana = function() {
return "banana";
};
var minionOne = new Minion();
var minionTwo = new Minion();
// "banana"
minionOne.sayBanana();
// "banana"
minionTwo.sayBanana();
We also can use a constructor function and alter the prototype of that function.
Notice the new keyword, this creates an object and the objects prototype will be the constructor function's prototype.
By convention, if a function is a constructor, it's name is capitalized
function Minion() {
this.dataPoint = "I am a Minion";
}
Minion.prototype.sayBanana = function() {
return "banana";
};
var minionOne = new Minion();
var minionTwo = new Minion();
minionOne.sayBanana();
minionTwo.sayBanana();
minionOne.dataPoint = "I have revolted";
console.log(minionOne.dataPoint);
console.log(minionTwo.dataPoint);
Constructor functions return 'this' as a copy. The copy can be changed.
function Minion() {
this.dataPoint = "I am a Minion";
}
Minion.prototype.sayBanana = function() {
return "banana";
};
var minionOne = new Minion();
var minionTwo = new Minion();
minionOne.sayBanana = function() {
return "HAHAHAHAHAHAHAHA - ANARCHY";
}
console.log(minionOne.sayBanana());
console.log(minionOne.__proto__.sayBanana())
console.log(minionTwo.sayBanana());
Copies can overwrite their prototype. You can access the prototype directly with __proto__