最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Pro Javascript Design Patterns errata? - Stack Overflow

programmeradmin0浏览0评论

Can anyone confirm that these samples from Chapter 3 of Pro Javascript Design Patterns are flawed and, if so, how fundamentally - are 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');

Can anyone confirm that these samples from Chapter 3 of Pro Javascript Design Patterns are flawed and, if so, how fundamentally - are 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');
Share Improve this question asked May 26, 2011 at 2:14 JofferJoffer 1,9392 gold badges21 silver badges23 bronze badges 2
  • Javascript isn't classical. Learn to prototype or use another language? read JS: The good parts, instead of what you are reading. – Glenn Ferrie Commented May 27, 2011 at 4:49
  • @GlennFerrieLive mostly for the record, I did/do know the prototypical inheritance mechanism, but can see why you assumed otherwise – Joffer Commented Nov 27, 2011 at 19:29
Add a ment  | 

6 Answers 6

Reset to default 7

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 acplish 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./code/javascript-programming-patterns/

and for immutable public properties, as was suggested, use Object.freeze and John Resig's great advice: http://ejohn/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"));
发布评论

评论列表(0)

  1. 暂无评论