JavaScript面向对象

2016-10-27  本文已影响6人  PhilicX

让我们来设计一个Book类吧,要求传入isbn、标题、作者创建,支持一个display方法(在html页面上显示图片,不过这里就不要求具体实现了)。

门户大开型

var Book = function(isbn, title, author) {
    if(isbn == undefined)
        throw new error('Book constructor requires an isbn.');
    this.isbn = isbn;
    this.title = title || 'No title specified';
    this.author = author || 'No author specified';
}
Book.prototype.display = function(){
    ...    
}

这种实现乍看可以满足所有要求,其实问题多多,首先就是没法检验最重要的参数--isbn的正确性,因为不合法的ISBN可能导致与之相关的封面图片无法找到从而使display方法无法工作。所以下面的实现方法强化了对参数的检查。


改进型---参数检查

 var Book = function(isbn, title, author) {
    if(isbn == undefined)
        throw new error('Book constructor requires an isbn.');
    this.isbn = isbn;
    this.title = title || 'No title specified';
    this.author = author || 'No author specified';
  }
  Book.prototype = {
      checkIsbn: function(isbn){
        if(isbn == undefined || typeof isbn != 'string') {
            return false;
        }
        isbn = isbn.replace(/-/, '');
        if(isbn.length!=10 && isbn.length != 13) {
            return false;
        }
        var sum = 0;
        if (isbn.length === 10) {
          if(!isbn.match(/^\d{9}/)) {
              return false;
          }
          for (var i=0;i<9;i++) {
              sum += isbn.charAt(i) * (10 - i);
          }
          var checksum = sum % 11;
          if (checksum === 10) checksum = 'X';
          if (isbn.charAt(9) != cheksum) {
              return false;
          }
        } else {
            if (!isbn.match(/^\d{12}/) != checksum) {
                return false;
            }
            for (var i=0;i<12;i++) {
                sum += isbn.charAt(i) * ((i % 2 === 0) ? 1 : 3);
            }
            var checksum = 10 - sum % 10;
            if(isbn.charAt(12) != checksum) {
                return false;
            }
          }
          return true;
        },
        display: function() {
            ...
        }
     },

这种实现方法虽然在构造器的部分对数据完整性进行了检验,但是如果使用者用下面的方式绕过构造器直接操作isbn属性,还是无法控制:

book.isbn = '14213321-321312';
book.display();

为了更好地保护内部数据,我们为每个属性都提供了取值器和赋值器

上一篇 下一篇

猜你喜欢

热点阅读