Pro Javascript Design Patterns errata?
Can anyone confirm that these samples from Chapter 3 of Pro Javascript Design Patterns are flawed and, if so, how fundamentally - a开发者_JAVA百科re they more than a typo or two away from producing the intended goal of 'class' constants in JavaScript? Thanks.
var Class = (function() {
// Constants (created as private static attributes).
var UPPER_BOUND = 100;
// Privileged static method.
this.getUPPER_BOUND() {//sic
return UPPER_BOUND;
}
...
// Return the constructor.
return function(constructorArgument) {
...
}
})();
/* Usage. */
Class.getUPPER_BOUND();
/* Grouping constants together. */
var Class = (function() {
// Private static attributes.
var constants = {
UPPER_BOUND: 100,
LOWER_BOUND: -100
}
// Privileged static method.
this.getConstant(name) {//sic
return constants[name];
}
...
// Return the constructor.
return function(constructorArgument) {
...
}
})();
/* Usage. */
Class.getConstant('UPPER_BOUND');
I think, this is wrong. As mentioned previously, "this" refers to the window object and the code also has a syntax error. The following code should accomplish the required goal:
var Class = (function () {
// Private static attributes.
var constants = {
UPPER_BOUND: 100,
LOWER_BOUND: -100
};
var sc = function (constructorArgument) {
};
// Privileged static method.
sc.getConstant = function (name) {
return constants[name];
};
// Return the constructor.
return sc;
})();
alert(Class.getConstant('UPPER_BOUND'));
The code can be trivially fixed as
var Class = {
UPPER_BOUND: 100
};
The rest of the code is over engineered or plain wrong and should be ignored.
If you care about being read only then set the writable flag to false (note the default is false).
var Class = {};
Object.defineProperty(Class, "UPPER_BOUND", {
value: 100,
enumerable: true,
configurable: true
});
Be wary of anything claiming to be "Pro" whatever. I haven't read the book, but my take on the code is as follows:
> var Class = (function() {
>
> // Constants (created as private static attributes).
The word "attributes" is wrong, it should be either "properties" or "variables" because they are variables, which can also be described as properties of the local activation/variable object.
> var UPPER_BOUND = 100;
>
> // Privileged static method.
> this.getUPPER_BOUND() {//sic
The code will be executed in a global context where this
is the window/global object. So if there is a global *getUPPER_BOUND* function, it will be called with no arguments. It is followed by a curly brace ({) which opens a block in a place where a block can't be, so that is a syntax error.
I presume the following was intended:
this.getUPPER_BOUND = function() {
which creates a getUPPER_BOUND property of the global/window object that is assiged the anonymous function on the RHS when the code is run.
> return UPPER_BOUND; }
>
> ...
>
> // Return the constructor.
> return function(constructorArgument) {
This is the function that is assigned to the global variable "Class".
> ...
> }
> })();
With fixes it may "work", but not elegantly. Any book with such glaring errors in the code has not been carefully written and certainly hasn't been properly reviewed before being published.
Use reputable online resources and continue to ask questions about anything you don't understand or think is in error. There are other forums for discussing javascript that can provide far more detailed answers for technical questions.
Check this out as a good alternative: http://www.klauskomenda.com/code/javascript-programming-patterns/
and for immutable public properties, as was suggested, use Object.freeze and John Resig's great advice: http://ejohn.org/blog/ecmascript-5-objects-and-properties/
and for a way to not clobber your global scope, add namespaces to jQuery: Is it possible to create a namespace in jQuery?
Got this to work, but not sure if this was what the authors intended it to be.
var Class = (function()
{
// Constants (created as private static attributes).
var constants =
{
UPPER_BOUND: 100,
LOWER_BOUND: -100
};
// Return the method(s).
return {
getConstant: function(name)
{
return constants[name];
}
}
}());
console.log(Class.getConstant('UPPER_BOUND')); // shows "100" in console
How about do it this way?
/* Grouping constants together. */
var Class = (function() {
// Private static attributes.
var constants = {
UPPER_BOUND: 100,
LOWER_BOUND: -100
}
// Return the constructor.
return new function(constructorArgument) {
// Privileged static method.
this.getConstant = function(name) {//sic
return constants[name];
}
}
})();
console.log(Class.getConstant("LOWER_BOUND"));
精彩评论