在js的学习中遇到了如下问题:
JavaScript的原型(prototype)方法如何访问私有变量?
百度搜出了相关答案,但都不是特别满意:
百度搜索关键字:prototype访问私有变量
https://segmentfault.com/q/1010000005121763
https://www.cnblogs.com/ZJAJS/archive/2012/09/11/2680640.html
http://www.softwhy.com/article-6288-1.html
百度搜索关键字:原型中访问私有变量
http://www.imooc.com/wenda/detail/572551
http://www.imooc.com/wenda/detail/572551
为此我做了以下试验,验证了使用getter的方法可行
这种方法既可以访问到私有变量,也能够访问到私有函数
function Test() {
var friends = []; // 私有变量
var result = 0; // 私有变量
function add(num) { // 私有函数
result += num;
}
this.getFriends = function () { // 为了能在原型中访问私有变量
return friends;
};
this.getResult = function () { // 为了能在原型中访问私有变量
return result;
};
this.add_func = function () { // 为了能在原型中访问私有函数
return add;
};
}
Test.prototype = {
constructor: Test,
appendFriend: function (friend) {
this.getFriends().push(friend); // 调用私有变量
return this;
},
add: function (num) {
this.add_func()(num); // 调用私有函数
return this;
}
};
var test1 = new Test();
var test2 = new Test();
/* 验证私有变量可用 */
test1.appendFriend('小明').appendFriend('小红');
console.log(test1.getFriends());// ['小明','小红'] 证明两个不同的对象不受干扰
console.log(test1.friends); // undefined 证明外部无法访问
test2.appendFriend('小白').appendFriend('小黑');
console.log(test2.getFriends());// ['小白','小黑'] 证明两个不同的对象不受干扰
console.log(test2.friends); // undefined 证明外部无法访问
/* 验证私有函数可用 */
test1.add(9).add(9);
test2.add(8).add(5);
console.log(test1.getResult()); // 18
console.log(test2.getResult()); // 13
console.log(Test.prototype.add);
用以上方案实现了一个图书馆案例
Book.js
function Book(bookID, bookName, bookPrice, oldLevel) {
this.bookID = bookID;
this.bookName = bookName;
this.bookPrice = bookPrice;
this.oldLevel = oldLevel;
}
Book.prototype.desc = function () {
return 'ID:' + this.bookID + ', 书名:' + this.bookName + ', 价格:' + this.bookPrice + ', 新旧程度' + this.oldLevel;
}
Library.js
function Library(libName) {
var store = []; // 私有变量
function isOldBook(bookObj) { // 私有函数
if(bookObj.oldLevel <= 0){
bookObj.oldLevel = 0;
return true;
}
return false;
}
this.libName = libName;
this.getStore = function () { // 为了能在原型中访问私有变量
return store;
};
this.isOldBook_func = function () { // 为了能在原型中访问私有函数
return isOldBook;
}
}
Library.prototype = {
constructor: Library,
saveBook: function (bookObj) {
if(!this.isOldBook_func()(bookObj)){ // 调用了私有函数
this.getStore().push(bookObj); // 使用了私有变量
console.log('成功存入: ' + bookObj.desc());
}else
console.log(bookObj.bookName + " 已经报废,无法存入");
},
borrowBook: function (bookID) {
for(var i=0; i<this.getStore().length; i++){
var bookObj = this.getStore()[i];
if(bookObj.bookID === bookID){
break;
}
}
if(i === this.getStore().length){
console.log('查无此书');
return;
}
var borrowBook = this.getStore().splice(i, 1)[0];
console.log('成功出借: \n' + borrowBook.desc());
return borrowBook;
},
queryAllBooks: function () {
var result = '图书馆内共有以下图书: \n';
for(var i=0; i<this.getStore().length; i++){
var bookObj = this.getStore()[i];
result += bookObj.desc() + '\n';
}
console.log(result);
return this.getStore();
},
queryBookByID: function (bookID) {
for(var i=0; i<this.getStore().length; i++){
var bookObj = this.getStore()[i];
if(bookObj.bookID === bookID){
break;
}
}
if(i === this.getStore().length){
console.log('查不到ID为: ' + bookID + '的书籍');
return;
}
console.log('查到ID为: ' + bookID + '的书籍: \n' + bookObj.desc());
return bookObj;
}
};
图书馆Demo.html
<script src="js/Book.js"></script>
<script src="js/Library.js"></script>
<script>
var book1 = new Book('TS001', 'JS基础', 30, -9);
var book2 = new Book('TS002', 'JS进阶', 40, -6);
var book3 = new Book('TS003', 'JS面向对象', 60, 8);
var book4 = new Book('TS004', '劲椎病康复秘籍', 1230, 10);
var library = new Library('小黑');
library.saveBook(book1); // JS基础 已经报废,无法存入
library.saveBook(book2); // JS进阶 已经报废,无法存入
library.saveBook(book3); // 成功存入: ID:TS003, 书名:JS面向对象, 价格:60, 新旧程度8
library.saveBook(book4); // 成功存入: ID:TS004, 书名:劲椎病康复秘籍, 价格:1230, 新旧程度10
library.borrowBook('TS004'); // 成功出借: ID:TS004, 书名:劲椎病康复秘籍, 价格:1230, 新旧程度10
library.queryAllBooks(); // 图书馆内共有以下图书: ID:TS003, 书名:JS面向对象, 价格:60, 新旧程度8
library.queryBookByID('TS004'); // 查不到ID为: TS004的书籍
</script>
网友评论