Javascript 中闭包(Closure)的探索(二)-私有变量和函数
利用匿名函数形成闭包可以在javascript中实现面向对象语言中的访问权限控制。即在javascript中也能实现私有变量。
参考网址:http://www.crockford.com/javascript/private.html
1.构造私有变量和公有变量
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>JsClosure2</title>
<script type="text/javascript">
function ClassFunc() {
this.publicMem = "public";
var privateMem = "private";
}
function closureTestClick() {
var test = new ClassFunc();
alert(test.publicMem);
alert(test.privateMem);
}
</script>
</head>
<body>
<input type="button" value="closureTest" onclick="closureTestClick()" />
</body>
</html>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <html xmlns= "http://www.w3.org/1999/xhtml" > <head> <title>JsClosure2</title> <script type= "text/javascript" > function ClassFunc() { this .publicMem = "public" ; var privateMem = "private" ; } function closureTestClick() { var test = new ClassFunc(); alert(test.publicMem); alert(test.privateMem); } </script> </head> <body> <input type= "button" value= "closureTest" onclick= "closureTestClick()" /> </body> </html> |
结果:alert(test.publicMem);可以正常显示,alert(test.privateMem);显示“undefined”。
结果分析:通过var定义的私有变量外界无法访问,如果要外界可以访问,需要构造get,set方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <script type= "text/javascript" > function ClassFunc() { this .publicMem = "public" ; var privateMem = "private" ; this .getprivateMem = function () { return privateMem; } this .setprivateMem = function (val) { privateMem = val; } } function closureTestClick() { var test = new ClassFunc(); alert(test.getprivateMem()); test.setprivateMem( "private changed!" ); alert(test.getprivateMem()); } </script> |
结果:如预期的一样显示“private”和“private changed!”。
2.私有函数
与私有变量的定义类似,不是通过this来定义的函数都是私有函数。
私有函数外部无法调用,但是可以通过内部的公有函数来调用。
测试代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <script type= "text/javascript" > function ClassFunc() { this .publicMem = "public" ; var privateMem = "private" ; this .getprivateMem = function () { return privateMem; } this .setprivateMem = function (val) { privateMem = val; } function privateFunc() { privateMem = "private changed!" ; // 此处的赋值并没有如预期的那样给test.publicMem成员赋值 this .publicMem = "public changed!" ; } this .callprivateFunc = function () { privateFunc(); } } function closureTestClick() { var test = new ClassFunc(); // 变更前 alert( "privateMem=" +test.getprivateMem()); alert( "publicMem=" + test.publicMem); test.callprivateFunc(); // 变更后 alert( "privateMem=" + test.getprivateMem()); alert( "publicMem=" + test.publicMem); } </script> |
变更后的结果privateMem如预期一样,而publicMem仍然是“public”,并没有改变。
这是因为函数privateFunc() 中this.publicMem 的this已经不是指向test这个js对象了。
关于this的指向为什么会变,参见我的第三篇文章,介绍javascript的scope的。
本例中为了能够修改test的publicMem属性,有两个方法:
其一,也是常用的,直接在外部修改publicMem,因为publicMem是公有变量。
1 | test.publicMem = "public changed!" ; |
其二,在函数callprivateFunc 和privateFunc中增加一个参数,显示的传入test对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <script type= "text/javascript" > function ClassFunc() { this .publicMem = "public" ; var privateMem = "private" ; this .getprivateMem = function () { return privateMem; } this .setprivateMem = function (val) { privateMem = val; } function privateFunc(obj) { privateMem = "private changed!" ; // 直接给obj.publicMem赋值 obj.publicMem = "public changed!" ; } this .callprivateFunc = function (obj) { privateFunc(obj); } } function closureTestClick() { var test = new ClassFunc(); // 变更前 alert( "privateMem=" +test.getprivateMem()); alert( "publicMem=" + test.publicMem); test.callprivateFunc(test); // 变更后 alert( "privateMem=" + test.getprivateMem()); alert( "publicMem=" + test.publicMem); } </script> |
标签:
javascript学习
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)