你的位置:首页 > 软件开发 > Java > Pro Javascript Design Patterns勘误Errata汇总(持续更新中)

Pro Javascript Design Patterns勘误Errata汇总(持续更新中)

发布时间:2012-02-16 18:00:07
结合从网上搜集的资料,现将Pro Javascript Design Patterns一书几处有错误嫌疑的地方整理出来。1. P.28: Chapter 3: Encapsulation and Information Hiding > Fully Exposed Object 错误类型:印刷错误+计算方法错误原代码为:Book.prototype = { checkIsbn: ...

结合从网上搜集的资料,现将Pro Javascript Design Patterns一书几处有错误嫌疑的地方整理出来。

1. P.28: Chapter 3: Encapsulation and Information Hiding > Fully Exposed Object  错误类型:印刷错误+计算方法错误    isbn = isbn.replace(/-/. ''); // Remove dashes.    var sum = 0;    isbn = isbn.replace(/-/g, ''); // Remove dashes.    var sum = 0;
    if(isbn.length === 10) { // 10 digit ISBN.
      if(!isbn.match(\^\d{9}\)) { // Ensure characters 1 through 9 are digits.
        return false;
      }


    var sum = 0;
    if(isbn.length === 10) { // 10 digit ISBN.
      If(!isbn.match(\^\d{9}\)) { // Ensure characters 1 through 9 are digits.
        return false;
      } var sum = 0; if (isbn.length === 10) { console.log("checking for 10..."); if (!isbn.match(/^\d{9}/)) { return false; } for ( var i = 0; i < 9; i++) { sum += isbn.charAt(i) * (10 - i); } var checksum = (11 - sum % 11) % 11; checksum = (checksum === 10) ? "X" : checksum; if (isbn.charAt(9) != checksum) { return false; } } else { if (!isbn.match(/^\d{12}/)) { return false; } for ( var i = 0; i < 12; i++) { sum += isbn.charAt(i) * ((i % 2 === 0) ? 1 : 3); } var checksum = (10 - sum % 10) % 10; if (isbn.charAt(12) != checksum) { return false; } }

...
};

关于验证ISBN号的正确计算方法,我参考了维基百科上的International Standard Book Number。这一点作者太疏忽大意了。

2. P.38: Chapter 3: Encapsulation and Information Hiding > Constants  错误类型:印刷错误+结构错误

原代码为:

var Class = (function() {    // Constants (created as private static attributes).  var UPPER_BOUND = 100;    // Privileged static method.  this.getUPPER_BOUND() {    return UPPER_BOUND;  }  ...  // Return the constructor.  return function(constructorArgument) {    ...  }})();/* Grouping constants together. */var Class = (function() {    // Private static attributes.  var constants = {    UPPER_BOUND: 100,    LOWER_BOUND: -100  }    // Privileged static method.  this.getConstant(name) {    return constants[name];  }  ...  // Return the constructor.  return function(constructorArgument) {    ...  }})();/* Usage. */Class.getConstant('UPPER_BOUND');

应更正为:

var Class = (function() {    // Constants (created as private static attributes).  var UPPER_BOUND = 100;    // Privileged static method.  this.getUPPER_BOUND=function() {    return UPPER_BOUND;  }  ...  // Return the constructor.  return function(constructorArgument) {    ...  }})();/* Grouping constants together. */var Class = (function() {    // Private static attributes.  var constants = {    UPPER_BOUND: 100,    LOWER_BOUND: -100  }    // Privileged static method.  this.getConstant=function(name) {    return constants[name];  }  ...  // Return the constructor.  return function(constructorArgument) {    ...  }})();/* Usage. */Class.getConstant('UPPER_BOUND');

关于此处代码的运行,有人提出并不能达到作者所提出的需求,因为即使照上面的方法更正后,由于this.getUPPER_BOUNDthis.getConstant都是在自执行函数的内部运行,这里的this实际上将指向全局变量,即window。在StacksOverflow上,有人提出此讨论,众人相继给出解决办法,敬请参阅原文。

3. P.89: Chapter 6: Chaining > Using Callbacks to Retrieve Data from Chained Methods  错误类型:印刷错误+结构错误

原代码为:

// Accessor without function callbacks: returning requested data in accessors.window.API = window.API || {};API.prototype = function() {  var name = 'Hello world';  // Privileged mutator method.  setName: function(newName) {    name = newName;    return this;  },  // Privileged accessor method.  getName: function() {    return name;  }}();// Implementation code.var o = new API;console.log(o.getName()); // Displays 'Hello world'.console.log(o.setName('Meow').getName()); // Displays 'Meow'.// Accessor with function callbacks.window.API2 = window.API2 || {};API2.prototype = function() {  var name = 'Hello world';  // Privileged mutator method.  setName: function(newName) {    name = newName;    return this;  },  // Privileged accessor method.  getName: function(callback) {    callback.call(this, name);    return this;  }}();// Implementation code.var o2 = new API2;o2.getName(console.log).setName('Meow').getName(console.log);// Displays 'Hello world' and then 'Meow'.

应更正为:

// Accessor without function callbacks: returning requested data in accessors.window.API = window.API || function(){};API.prototype = function() {  var name = 'Hello world';
return {
// Privileged mutator method. setName: function(newName) { name = newName; return this; }, // Privileged accessor method. getName: function() { return name; }
}

}();// Implementation code.var o = new API;console.log(o.getName()); // Displays 'Hello world'.console.log(o.setName('Meow').getName()); // Displays 'Meow'.// Accessor with function callbacks.window.API2 = window.API2 || function(){};API2.prototype = function() { var name = 'Hello world'; return {// Privileged mutator method. setName: function(newName) { name = newName; return this; }, // Privileged accessor method. getName: function(callback) { callback.call(this, name); return this; }
}
}();// Implementation code.var o2 = new API2;o2.getName(console.log).setName('Meow').getName(console.log);// Displays 'Hello world' and then 'Meow'.

这个问题是http://www.apress.com/9781590599082/上有人提出的。

4. P.100: Chapter 7: The Factory Pattern > XHR Factory  错误类型:印刷错误?结构错误?

原代码为:

/* SimpleHandler class. */var SimpleHandler = function() {}; // implements AjaxHandlerSimpleHandler.prototype = {  request: function(method, url, callback, postVars) {  ...  },  createXhrObject: function() { // Factory method.    var methods = [      function() { return new return methods[i];    }        // If we reach this point, none of the methods worked.    throw new Error('SimpleHandler: Could not create an XHR object.');  } };

应更正为:

/* SimpleHandler class. */var SimpleHandler = function() {}; // implements AjaxHandlerSimpleHandler.prototype = {  request: function(method, url, callback, postVars) {  ...  },  createXhrObject: function() { // Factory method.    var methods = [      function() { return new return methods[i]();    }        // If we reach this point, none of the methods worked.    throw new Error('SimpleHandler: Could not create an XHR object.');  } };

这一错误很可能是作者没有测试代码,照书中所述,createXhrObject要在第一次运行之后记住当前的运行环境中能够使用的HttpRequest对象,methods数组中的对象为函数,因此要用一个括号执行后才能得到真正的对象。

5. P.130: Chapter 9: The Composite Pattern > Form Validation  错误类型:印刷错误

原代码为:

/* Field class, abstract. */var Field = function(id) { // implements Composite, FormItem  this.id = id;  this.element;};...Field.prototype.save = function() {  setCookie(this.id, this.getValue);};

应更正为:

/* Field class, abstract. */var Field = function(id) { // implements Composite, FormItem  this.id = id;  this.element;};...Field.prototype.save = function() {  setCookie(this.id, this.getValue());};

6. P.155: Chapter 11: The Adapter Pattern > Adapting an Email API  错误类型:印刷错误

原代码为:

// dedMail application interface.        var dedMail = (function() {          function request(id, type, callback) {              ...          }          return {              ...            formatMessage: function(e) {              var e = e || window.event;              try {                e.preventDefault();              }               catch(ex) {                e.returnValue = false;              }              var targetEl = e.target || e.srcElement;              var id = targetEl.id.toString().split('-')[1];              dedMail.getMail(id, function(msgObject) {                var resp = eval('('+msgObject+')');                ...                messagePane.innerHTML = DED.util.substitute(details, resp);              }          };         })();                 // Set up mail implementation.        addEvent(window, 'load', function() {          var threads = getElementsByClass('thread', 'a');          var messagePane = $('message-pane');          for (var i=0, len=threads.length; formatMessage );          }        });

应更正为:

// dedMail application interface.
        var dedMail = (function() {          function request(id, type, callback) {              ...          }          return {              ...            formatMessage: function(e) {              var e = e || window.event;              try {                e.preventDefault();              }               catch(ex) {                e.returnValue = false;              }              var targetEl = e.target || e.srcElement;              var id = targetEl.id.toString().split('-')[1];              dedMail.getMail(id, function(msgObject) {                var resp = eval('('+msgObject+')');                ...                messagePane.innerHTML = DED.util.substitute(details, resp);              })            }          };         })();                 // Set up mail implementation.        addEvent(window, 'load', function() {          var threads = getElementsByClass('thread', 'a');          var messagePane = $('message-pane');          for (var i=0, len=threads.length; dedMail.formatMessage );          }        });

7. P.161,162,165,166: Chapter 12: The Decorator Pattern > The Structure of the Decorator   错误类型:结构错误

在多个页码处均为同一错误类型,仅举其中一处为例。P.161:

原代码为:

/* HeadlightDecorator class. */var HeadlightDecorator = function(bicycle) { // implements Bicycle  this.superclass.constructor(bicycle); // Call the superclass's constructor.}extend(HeadlightDecorator, BicycleDecorator); // Extend the superclass.HeadlightDecorator.prototype.assemble = function() {  return this.bicycle.assemble() + ' Attach headlight to handlebars.';};HeadlightDecorator.prototype.getPrice = function() {  return this.bicycle.getPrice() + 15.00;};

应更正为:

/* HeadlightDecorator class. */var HeadlightDecorator = function(bicycle) { // implements Bicycle  HeadlightDecorator.superclass.constructor.call(this, bicycle); // Call the superclass's constructor.}extend(HeadlightDecorator, BicycleDecorator); // Extend the superclass.HeadlightDecorator.prototype.assemble = function() {  return this.bicycle.assemble() + ' Attach headlight to handlebars.';};HeadlightDecorator.prototype.getPrice = function() {  return this.bicycle.getPrice() + 15.00;};

8. P.191: Chapter 13: The Flyweight Pattern > Sotring Instances for Later Reuse   错误类型:结构错误

原代码为:

			var DialogBoxManager = (function() {				var created = [];				return {					displayDialogBox : function(id, header, body, footer) {						var inUse = this.numberInUse();						if (inUse > created.length) {							created.push(this.createDialogBox(id));						}						created[i].show(header, body, footer);					},					createDialogBox : function(id) {						return new DialogBox(id);					},					numberInUse : function() {						var inUse = 0;						for ( var i = 0; i < created.length; ++i) {							console.log(created[i].state());							if (created[i].state() == "visible") {								inUse++;							}						}						return inUse;					}				}			})();

应更正为:

			var DialogBoxManager = (function() {				var created = [];				return {					displayDialogBox : function(header, body, footer) {						(this.getFirstHiddenDialogBox() || this.createDialogBox()).show(header, body, footer);					},					createDialogBox : function() {						var db = new DialogBox(this.numberInUse());						created.push(db);						return db;					},					getFirstHiddenDialogBox : function() {						for ( var i = 0; i < created.length; ++i) {							if (created[i].state() != "visible") {								return created[i];							}							continue;						}						return null;					},					numberInUse : function() {						var inUse = 0;											for ( var i = 0; i < created.length; ++i) {							if (created[i].state() == "visible") {								inUse++;							}						}						return inUse;					}				}			})();

原代码中inUse > created.length是显然行不通的,inUse永远也不可能大于created.length,其判断也就失去了意义。改进后的代码将能在调用自动displayDialogBox时判断是否有隐藏的已经建立的DialogBox,如果有即用之,如果没有即调用createDialogBox创建一个新的,numberInUse在createDialogBox函数中使用。

本文来自pinocchioatbeijing在博客园的博客,文章URL:http://www.cnblogs.com/pinocchioatbeijing/archive/2012/02/01/2334126.html,转载请注明,并欢迎大家不吝赐教。

原标题:Pro Javascript Design Patterns勘误Errata汇总(持续更新中)

关键词:javascript,Design,Patterns,勘误,Errata,汇总,设计模式

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。