I'm currently digging deeper in the really nice prototypical delegation of Objects in JavaScript. As far as I understood the simple types (Numbers, strings and booleans) as well as functions and arrays get their base methods delegated from the Object.prototype
. A good example is the toString
methods. Because of JavaScripts mutability of Objects it is possible to change these methods. Also because of it's dynamical nature, these changes will be immediately available to all prototypes that are linked to the Object.prototype
.
Here is a basic example of how dynamical prototype linkage should work:
var myFirstObject = {
myMethod: function () {
console.log('this is the method from myFirstObject');
}
},
mySecondObject = Object.create(myFirstObject);
mySecondObject.myMethod(); // "this is the method from myFirstObject"
myFirstObject.myMethod = function () {
console.log('this is a dynamic change of myMethod from myFirstObject');
};
mySecondObject.myMethod(); // "this is a dynamic change of myMethod from myFirstObject"
mySecondObject.myMethod = function () {
console.log('this is the method from mySecondObject')
};
mySecondObject.myMethod(); // "this is the method from mySecondObject"
delete mySecondObject.myMethod;
mySecondObject.myMethod(); // "this is a dynamic change of myMethod from myFirstObject"
However this doesn't seems to work as expected for the default methods like toString
:
var myFunction = function () {};
Object.prototype.myCustomMethod = function () {
console.log('This is a custom function on the Object prototype');
};
myFunction.myCustomMethod(); // "This is a custom function on the Object prototype"
Object.prototype.toString = function () {
console.log('Don\'t mess around with the Object prototype default methods');
}
myFunction.toString(); // "function () {}" <-- ???
Function.prototype.toString = function () {
console.log('Don\'t mess around with the Function prototype default methods');
};
myFunction.toString(); // "Don't mess around with the Function prototype default methods"
delete Function.prototype.toString;
myFunction.toString(); // "Don't mess around with the Object prototype default methods" <-- ???
So my question is: What kind of magic is happening for default methods like toString
is there a real delegation between the Object.prototype
and the Function.prototype
or just a simple copy?
Its called the "Prototype chain" and starts at the bottom and moves up eventually to Object
which is the base for all objects types.
Function
inherits the Object prototype and has its own prototype. So when the JavaScript interpreter sees Function.toString
it will first look for toString
in the Function.prototype
. only if it can not be found will it move up to the next prototype, which in this case is the Object.prototype
This is why you Object.toString is not called in the example you have given.
This is done for all object properties. It is important to note that each step up the prototype chain you go the longer it will take to access that property as the interpreter will always start at the bottom and work up. Each prototype search takes CPU cycles so it is best to have the method or property on the object you are accessing rather than have one common method further up the prototype chain, such as Object
.
/* Sorry I do not remember if it "down" or "up" the chain, will correct when I find the common vernacular for which direction Object is. */
I now have the correct direction.