zoukankan      html  css  js  c++  java
  • Javascript 中闭包(Closure)的探索(三)私有函数中的this

    在上一篇文章中,私有函数里给公有变量this.publicMem 赋值并没有达到预期的效果。(示例代码参见Javascript 中闭包(Closure)的探索(二)-私有变量和函数

    原因在于每个函数被调用时,会产生自己的scope,在此scope中,会生成自己函数内使用的变量,方法等等。

    对于公有的变量和方法(如上篇文章例子中的this.publicMem和this.callprivateFunc等)会在函数ClassFunc被new出来时一起加入到ClassFunc的scope中,因此在函数callprivateFunc中的this指针就是指向当前new出来的ClassFunc对象。

    而对于私有函数privateFunc,是在被调用时才形成自己的scope的,由于这个函数不在ClassFunc的scope中,因此其中的this指针就是指向全局的window对象。

    验证代码如下:

    <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!";
                // 相当于给window对象的publicMem属性赋值
                // 因为当前window对象不存在publicMem属性,所以新建了publicMem属性。
                // 此时test对象的this.publicMem没变
                this.publicMem = "public changed!";
            }
    
            this.callprivateFunc = function() {
                privateFunc();
            }
        }
    
        function closureTestClick() {
            var test = new ClassFunc();
            // 变更前
            alert("privateMem=" + test.getprivateMem());
            alert("publicMem=" + test.publicMem);
            // 此时window.publicMem为undefined
            alert("publicMem=" + window.publicMem);
            test.callprivateFunc(test);
            // 变更后
            alert("privateMem=" + test.getprivateMem());
            alert("publicMem=" + test.publicMem);
            // 此时window.publicMem为"public changed!"
            alert("publicMem=" + window.publicMem);
        }
    </script>
    

    如果需要在私有函数中利用this操作当前对象test,而非window对象。可以利用javascript内置的两个方法callapply,即显示的将对象传递给私有函数privateFunc。

    代码如下:

    <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!";
                    this.publicMem = "public changed!";
                }
    
                this.callprivateFunc = function() {
                    privateFunc.apply(this);
                    //或者
                    //privateFunc.call(this);
                }
            }
    
            function closureTestClick() {
                var test = new ClassFunc();
                // 变更前
                alert("privateMem=" + test.getprivateMem());
                alert("publicMem=" + test.publicMem);
                // 此时window.publicMem为undefined
                alert("publicMem=" + window.publicMem);
                test.callprivateFunc(test);
                // 变更后
                alert("privateMem=" + test.getprivateMem());
                // 此时test.publicMem被改变了
                alert("publicMem=" + test.publicMem);
                // 此时window.publicMem为undefined
                alert("publicMem=" + window.publicMem);
            }
        </script>
    

    因此,我们在js中使用私有函数的时候一定要注意这个特点,这也是js和其他真正面向对象的语言(C#,java等)的区别之一吧!

    如有理解不对的地方,还希望各位不吝指教!

  • 相关阅读:
    Java 21-Spring知识
    Java18-黑马旅游网学习制作
    Java17-Filter&Listener&Json&redis&maven
    python发邮件
    一元模型拟合(OLS和插值np拟合)
    一元模型拟合
    2.13 描述性统计(平均数,中位数,中数,数据的离散度(极差,平均绝对偏差,方差标准差))
    tushare 股票数据获取,收益率计算,直方图绘制
    主板指数数据的爬取(selenium处理JS)
    网页整页截图小工具
  • 原文地址:https://www.cnblogs.com/wang_yb/p/1729646.html
Copyright © 2011-2022 走看看