zoukankan      html  css  js  c++  java
  • 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>

    <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方法。

    <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来定义的函数都是私有函数。

    私有函数外部无法调用,但是可以通过内部的公有函数来调用。

    测试代码如下:

    <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.publicMemthis已经不是指向test这个js对象了。

    关于this的指向为什么会变,参见我的第三篇文章,介绍javascript的scope的。

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

    其一,也是常用的,直接在外部修改publicMem,因为publicMem是公有变量。

    test.publicMem = "public changed!";
    

    其二,在函数callprivateFuncprivateFunc中增加一个参数,显示的传入test对象。

    <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>
    
  • 相关阅读:
    C语言强化(五)输出一串数中最小的 k 个
    C语言强化(四)求和为某个值的二叉树路径
    C语言强化(三)求子数组的最大和
    C语言强化(二)设计可以求最小元素的栈
    【转】深入理解Major GC, Full GC, CMS
    一步步优化JVM六:优化吞吐量
    一步步优化JVM五:优化延迟或者响应时间
    一步步优化JVM四:决定Java堆的大小以及内存占用
    一步步优化JVM三:GC优化基础
    一步步优化JVM二:JVM部署模型和JVM Runtime
  • 原文地址:https://www.cnblogs.com/wang_yb/p/1729070.html
Copyright © 2011-2022 走看看