西红柿爱番茄

Feed Rss

模拟私有方法和公有方法

01.13.2010, Javascript, by .

今天邮件收到了James Padolsey的blog的一片博文《Encapsulation in JavaScript》,他编写了一个Class方法,这个方法参数中可以通过使用下划线的方式来声明私有方法和私有属性,声明为私有的方法和属性,实例对象是无法调用的,只能通过公有方法来调用。思路不错 ,看了一下源码,有点晕。干脆就自己动手来实现另外一种思路了,基本思路跟他的也是比较类似的。看下面的调用的例子:

[javascript]
var Person = Class({
init: function(name, age){ //这个方法是必须要声明,初始化构造函数
this.name = name;
this.age = age;
},
setName: function(name){
this.name = name;
},
_getName: function(){ //private method
return this.name;
},
setAge: function(age){
this.age = age;
},
_getAge: function(){ //private method
return this.age;
},
getString: function(){
//在同一个参数对象内,公有函数可以调用私有函数
return this._getName() + " " + this._getAge();
}
});

var person = new Person("supersha", 44);
//person.setName("super");
//alert(person.name); //return "undefined"
//alert(person.age); //return "undefined"
person.setName("super"); //重新设置属性值
alert(person.getString()); //return "super 44"
alert(person._getName()); //error
[/javascript]

上面的_getName和_getAge两个方法就是私有方法,在实例化对象外部是不能访问的,同时值得说明的是,Class内声明的属性也全部都是私有的,实例化外部不可以访问。

下面是Class函数的源码,原理也很简单,没什么新意:
[javascript]
//init方法是Class参数对象中必须要带有的,用于初始化构造函数
function Class(o){
//privateObject用于储存Class函数参数对象的方法
var privateObject = {};
var F = null;

//将Class参数对象的方法传递给privateObject
for (var key in o) {
if (o.hasOwnProperty(key)) {
privateObject[key] = o[key];
}
}

//声明构造函数的执行代码
if (privateObject["init"]) {
F = function(){
privateObject.init.apply(privateObject, arguments);
}
}
else { return "There must be a init function in the Class’s pramas."; }

//给构造函数添加"公有方法"
for (var k in privateObject) {
if (privateObject.hasOwnProperty(k) && k.indexOf("_") !== 0) {
F.prototype[k] = (function(key){
return function(){
return privateObject[key].apply(privateObject, arguments);
}
})(k);
}
}
//返回构造函数
return F;
}
[/javascript]
推荐阅读:《Encapsulation in JavaScript

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>