Augmenting types in JavaScript
I'm reading Douglas Crockford's JavaScript: The Good Parts, and I'm a little confused about something. In chapter 4, under Augmenting Types, he creates a shortcut for adding a method.
Function.prototype.method = function (name, func) {
this.prototype[name] = func;
return this;
};
He says:
By augmenting Function.prototype with a 'method' method, we no longer have to type the name of the prototype property. That bit of ugliness can now be hidden.
He then goes on to use this to add an 'integer' method to the number prototype with this.
Number.method('integer', function () {
return Math[this < 0 ? 'ceil' : 'floor'](this);
});
document.writeln((-10 / 3).integer()); // -3
I'm a little confused here... because we added a 'method' method to the Function prototype, not the Number prototype. And to my knowledge, the Number object does not inherit from the Function prototype (though maybe I'm wrong there). I see that this works, but I don't understand why Number objects are able to make use of this 'method' method to add...开发者_JAVA技巧 methods.
I assume this works because Number
is a function.
As shown here: http://jsfiddle.net/zCbdB/1
Number
is in fact a function. Any constructor is a function.
One way to think about types in javascript is to say that a type is just a function Foo
that has a .prototype
property. This is the prototype of any object that gets created with the new
keyword, as in new Foo()
. By convention Foo
is capitalized to indicate that it is a constructor.
Function.prototype.method = function (name, func) {
this.prototype[name] = func;
return this;
};
Well in this statement block you have created a method called method that is accessible to all Objects through prototypal inheritance. Functions derive from Function.prototype which derives from Object.prototype. Thus Strings and Numbers will be able to access the Object.prototype method called method in this declaration.
Number.method('integer', function () {
return Math[this < 0 ? 'ceil' : 'floor'](this);
});
document.writeln((-10 / 3).integer()); // -3
In this second block you are basically calling the method that is already available in the Object prototype and passing the required parameter in this case name = 'integer' and value equal to
function () {
return Math[this < 0 ? 'ceil' : 'floor'](this);
});
Finally in the last statement you pass in the name value pair for the result of -3
Here's an example that might help:
var num = Number('1.2');
alert(num instanceof Number); // true
alert(num instanceof Function); // false
alert(Number instanceof Number); // false
alert(Number instanceof Function); // true
Another way of thinking about it is that in Javascript Function
pulls double duty as the class type - the type of types. Therefore this is adding a method to types.
精彩评论