Javascript is a dual-style language. You can program it procedurally, like C, or in an object-oriented manner, somewhat like Ruby or Perl. The basic function/class declaration takes the form:
function Name (parameter_list) { code_block }
The form above is really just syntactic sugar for function pointer assignment syntax:
var Name = function (parameter_list) { code_block }
Name is an alias for an anonymous function pointer. Furthermore, every object instance in Javascript is more or less equivalent to assignment of a simple anonymous hash table:
var Name = { code_block }
Above, we create an object called Name. There is no prototype (ancestral shadow object) attached to Name, as you would normally get if you used new() (which you can't with a hash), but member methods and properties assigned inline or posthumously will function just as if they were part of an object.
Similarly, a function declaration also doubles as a class declaration in Javascript:
// namespace collision wrapper START (function () { /* this is our dual class/function */ function Klass(param) { this.inline_property = "I'm an inline_property."; this.inline_method = function () { return "I'm an inline_method."; } return "I'm a return value."; }; /*********************************/ /* add some members posthumously */ /*********************************/ /* Add static members to Klass */ Klass.static_property = "I'm a static_property."; Klass.static_method = function () { return "I'm a static_method."; } /* Add instance members to all objects created from Klass */ Klass.prototype.instance_property = "I'm an instance_property."; Klass.prototype.instance_method = function foo() { return "I'm an instance_method."; } /**********************************************************/ /* Now let's see the different types of calls we can make */ /**********************************************************/ var d = document; /* call as a plain old function */ d.write ("[Call as a function]<p>"); // prints "I'm a return value." d.write ( Klass("parameter") + "<p>"); /* call as a static Class */ d.write ("[Call as a static class]<p>"); // prints "I'm a static_property." d.write ( Klass.static_property + "<p>"); // prints "I'm a static_method." d.write ( Klass.static_method() + "<p>"); /* call as an instance of Klass (an object) */ d.write ("[Call as an Object]<p>"); K = new Klass(); // prints "I'm an inline_property" d.write ( K.inline_property + "<p>"); // prints "I'm an inline_method" d.write ( K.inline_method() + "<p>"); // prints "I'm an instance_property" d.write ( K.instance_property + "<p>"); // prints "I'm an instance_method" d.write ( K.instance_method() + "<p>"); }) (); // namespace collision wrapper END
The point of the code above is to show that a function declaration can double as a class declaration. If the function Name (or Class Name) is new()-ed, it has nearly the full capability of an object. So not only is an object mostly interchangeable with a hash, but a class is mostly interchangeable with a function.
Class <=> Function and Object <=> Hash
How's that for confusing? Little old Javascript is not as simple as it seems!
No comments:
Post a Comment