开发者社区> zting科技> 正文

Javascript 中闭包(Closure)的探索(二)-私有变量和函数

简介:
+关注继续查看

利用匿名函数形成闭包可以在javascript中实现面向对象语言中的访问权限控制。即在javascript中也能实现私有变量。

参考网址:http://www.crockford.com/javascript/private.html

 

1.构造私有变量和公有变量

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的。

本例中为了能够修改testpublicMem属性,有两个方法:

其一,也是常用的,直接在外部修改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>



本文转自wang_yb博客园博客,原文链接:http://www.cnblogs.com/wang_yb/archive/2010/05/06/1729070.html,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
TypeScript constructor signature 类型的变量赋值方式
TypeScript constructor signature 类型的变量赋值方式
21 0
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
20690 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
18989 0
PHP获取当前url路径的函数及服务器变量:$_SERVER["QUERY_STRING"],$_SERVER["REQUEST_URI"],$_SERVER["SCRIPT_NAME"],$_SER
1,$_SERVER["QUERY_STRING"] 说明:查询(query)的字符串 2,$_SERVER["REQUEST_URI"] 说明:访问此页面所需的URI 3,$_SERVER["SCRIPT_NAME"] 说明:包含当前脚本的路径 4,$_SERV...
843 0
Java 获取成员变量&amp;构造函数
获取成员变量&构造函数 一、成员变量是java.lang.reflect.Field的对象 1、Field类封装了关于成员变量的操作 2、Field[] fs = c.getFields()方法获取所有public的成员变量Field[]信息 3、c.
723 0
+关注
3550
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载