在平常工作中大家都会默认用下划线来表示私有方法和属性:
View Code
1 var Book = function(isbn, title, author) { // implements Publication 2 this.setIsbn(isbn); 3 } 4 Book.prototype = { 5 _checkIsbn: function(isbn) { 6 ... 7 }, //公认的私有方法 8 getIsbn: function() { 9 return this._isbn; 10 }, 11 setIsbn: function(isbn) { 12 if(!this._checkIsbn(isbn)) throw new Error('Book: Invalid ISBN.'); 13 this._isbn = isbn; 14 }, 15 };
这种其实不是规范的私有成员,在javascript中,只要函数具有作用域,也就是说在一个函数内部定义的变量在函数外部无法访问,这也是私有成员的本质。利用这种技术,可以在js中定义私有成员,这里要用到的就是闭包:
View Code
1 function foo() { 2 var a = 10; 3 4 function bar() { 5 a *= 2; 6 } 7 8 bar(); 9 return a; 10 }
前面所讲的作用域和闭包可以用来创建静态成员,包括公用和私有的,下面就是加了静态属性和方法的Book类:
View Code
1 var Book = (function() { 2 3 // 私有静态属性 4 var numOfBooks = 0; 5 6 // Private static method. 7 function checkIsbn(isbn) { 8 ... 9 } 10 11 // 返回构造函数 12 return function(newIsbn, newTitle, newAuthor) { // implements Publication 13 14 // 私有属性 15 var isbn, title, author; 16 17 // 特权方法 18 this.getIsbn = function() { 19 return isbn; 20 }; 21 this.setIsbn = function(newIsbn) { 22 if(!checkIsbn(newIsbn)) throw new Error('Book: Invalid ISBN.'); 23 isbn = newIsbn; 24 }; 25 26 this.getTitle = function() { 27 return title; 28 }; 29 this.setTitle = function(newTitle) { 30 title = newTitle || 'No title specified'; 31 }; 32 33 this.getAuthor = function() { 34 return author; 35 }; 36 this.setAuthor = function(newAuthor) { 37 author = newAuthor || 'No author specified'; 38 }; 39 40 // Constructor code. 41 numOfBooks++; // Keep track of how many Books have been instantiated 42 // with the private static attribute. 43 if(numOfBooks > 50) throw new Error('Book: Only 50 instances of Book can be ' 44 + 'created.'); 45 46 this.setIsbn(newIsbn); 47 this.setTitle(newTitle); 48 this.setAuthor(newAuthor); 49 } 50 })(); 51 52 // 公用静态方法 53 Book.convertToTitleCase = function(inputString) { 54 ... 55 }; 56 57 // 公用无特权方法. 58 Book.prototype = { 59 display: function() { 60 ... 61 } 62 };