// 方法一传统方法
var Book = function(isbn,title,author){
if(isbn == undefind) throw new Error("Book constructor requires an isbn.");
this.isbn = isbn;
this.title = title || "no title specified";
this.author = title || "no author specified";
}
Book.prototype.display = function(){
console.log(this.constructor);
}
//方法二 加强 对isbn完整性进行检查
var Book2 = function(isbn,title,author){
this.setIsbn(isbn);
this.setTitle(title);
this.setAuthor(author);
};
Book2.prototype = {
checkIsbn:function(isbn){
if(isbn == undefind || 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 = 11 - sum % 11;
if(checksum === 10) checksum = "X";
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 = sum % 10;
if(isbn.charAt(12) != checksum){
return false;
}
}
return true; // 通过检测
},
getIsbn: function(){
return this.isbn;
}
setIsbn:function(isbn){
if(!this.checkIsbn(isbn)) throw new Error("Book: Invalid ISBN.");
this.isbn = isbn;
},
getTitle: function(){
return this.title;
},
setTitle: function(title){
this.title = title || "no title specified";
},
getAuthor:function(){
return this.author;
},
setAuthor:function(author){
this.author = author || "no author specified";
},
display:function(){
console.log("书号:"+ this.isbn + "书名:" + this.title+"作者"+this.author);
}
};
//以上代码实传统方法最好结果了,定义了接口 以及赋值等 但任然可以访问到内部其他
//用命名规范区别私有成员
var Book3 = function(isbn,title,author){
this.setIsbn(isbn);
this.setTitle(title);
this.setAuthor(author);
};
Book2.prototype = {
_checkIsbn:function(isbn){
if(isbn == undefind || 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 = 11 - sum % 11;
if(checksum === 10) checksum = "X";
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 = sum % 10;
if(isbn.charAt(12) != checksum){
return false;
}
}
return true; // 通过检测
},
getIsbn: function(){
return this._isbn;
}
setIsbn:function(isbn){
if(!this._checkIsbn(isbn)) throw new Error("Book: Invalid ISBN.");
this._isbn = isbn;
},
getTitle: function(){
return this._title;
},
setTitle: function(title){
this._title = title || "no title specified";
},
getAuthor:function(){
return this._author;
},
setAuthor:function(author){
this._author = author || "no author specified";
},
display:function(){
console.log("书号:"+ this._isbn + "书名:" + this._title+"作者"+this._author);
}
};
// 闭包作用域是词法性的, 函数运行在创建的作用域 而不是调用的作用域
//用闭包实现私有成员
var Book4 = function(newIsbn,newTitile, newAuthor){
//私有成员
var isbn,title,author;
//私有方法 private method
function checkIsbn(isbn){
...省略
}
//特权方法 privileged methods
this.getIsbn = function(){
return isbn;
}
this.setIsbn = function(){
if(!checkIsbn(newIsbn)) throw new Error("Book: Invalid isbn");
isbn = newIsbn;
};
this.getTitle = function(){...省略};
//构造函数 代码
this.setIsbn(newIsbn);
this.setTitle(newTitile);
this.setAuthor(newTitile);
};
//公有方法 非特权
Book.prototype = {
display:function(){
...
}
}
// 该方法没生成一个实列就会存储一份副本 占用空间 也不适合派生子类 子类无法访问超类的私有