zoukankan      html  css  js  c++  java
  • JS闭包研究、自造困扰与解答

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <script>
            //------------------------------------------------------------------
            var intCount = 0;
            function Add() {
                return intCount++;
            }
            //------------------------------------------------------------------
            var AddPkgErr = function () {
                var intCount = 0;
                //var intCountErr = 0;
                AddPkgErr.prototype.Add = function () {
                    //return intCount++;
                    return intCount++;
                    //return intCountErr++;
                }
            }
            //------------------------------------------------------------------
            var AddPkgOK = function () {
                //定義包的變量
                AddPkgOK.prototype.intCount = 0;
                //AddPkgOK.prototype.intCountOK = 0;
                //定義包的方法
                AddPkgOK.prototype.Add = function () {
                    return AddPkgOK.prototype.intCount++;
                    //return AddPkgOK.prototype.intCountOK++;
                }
            }
            var AddPkg3 = function () {
                //定義包的變量
                this.intCount = 0;
                //定義包的方法
                this.Add = function () {
                    return this.intCount++;
                }
            }
            //====================================================================
            function test1()
            {
                WriteLog("=====================================");
                WriteLog("非閉包,每次累加:" + Add());
            }
    
            function test21() {
                WriteLog("=====================================");
                var objAddPkg = new AddPkgErr();
                WriteLog("閉包單組21,每次都是新的:" + objAddPkg.Add());
            }
            function test22() {
                WriteLog("=====================================");
                var objAddPkg = new AddPkgOK();
                WriteLog("閉包單組22,每次都是新的:" + objAddPkg.Add());
            }
            function test3() {
                WriteLog("=====================================");
                WriteLog("閉包多組,每組都是新的並且組與組之間互不影響(錯誤結果)");
                var objAddPkg1 = new AddPkgErr();
                WriteLog("第一組,第一次:" + objAddPkg1.Add());
                WriteLog("第一組,第二次:" + objAddPkg1.Add());
                WriteLog("第一組,第三次:" + objAddPkg1.Add());
                WriteLog("=====================================");
                var objAddPkg2 = new AddPkgErr();
                WriteLog("第二組,第一次:" + objAddPkg2.Add());
                WriteLog("第二組,第二次:" + objAddPkg2.Add());
                WriteLog("第二組,第三次:" + objAddPkg2.Add());
                WriteLog("=====================================");
                WriteLog("第一組,第四次:" + objAddPkg1.Add());
                WriteLog("第二組,第四次:" + objAddPkg2.Add());
            }
            function test4() {
                WriteLog("=====================================");
                WriteLog("閉包多組,每組都是新的並且組與組之間互不影響(預期結果)");
                var objAddPkg1 = new AddPkgOK();
                WriteLog("第一組,第一次:" + objAddPkg1.Add());
                WriteLog("第一組,第二次:" + objAddPkg1.Add());
                WriteLog("=====================================");
                var objAddPkg2 = new AddPkgOK();
                WriteLog("第二組,第一次:" + objAddPkg2.Add());
                WriteLog("第二組,第二次:" + objAddPkg2.Add());
                WriteLog("=====================================");
                WriteLog("第一組,第三次:" + objAddPkg1.Add());
                WriteLog("第二組,第三次:" + objAddPkg2.Add());
            }
    
            function test5() {
                WriteLog("=====================================");
                WriteLog("閉包多組,每組都是新的並且組與組之間互不影響(預期結果)");
                var objAddPkg1 = new AddPkg3();
                WriteLog("第一組,第一次:" + objAddPkg1.Add());
                WriteLog("第一組,第二次:" + objAddPkg1.Add());
                WriteLog("=====================================");
                var objAddPkg2 = new AddPkg3();
                WriteLog("第二組,第一次:" + objAddPkg2.Add());
                WriteLog("第二組,第二次:" + objAddPkg2.Add());
                WriteLog("=====================================");
                WriteLog("第一組,第三次:" + objAddPkg1.Add());
                WriteLog("第二組,第三次:" + objAddPkg2.Add());
            }
            function WriteLog(sMsg) {
                txtMsg.innerHTML = txtMsg.innerHTML + sMsg + "
    ";
            }
        </script>
    
    </head>
    <body>
        <input id="btnTest1" type="button" onclick="test1();" value="非閉包" />
        <input id="btnTest2" type="button" onclick="test21();"  value="閉包單組" />
        <input id="btnTest3" type="button" onclick="test22();" value="閉包單組" />
        <input id="btnTest4" type="button" onclick="test3();" value="閉包多組多次(錯誤結果)" />
        <input id="btnTest5" type="button" onclick="test4();" value="閉包多組多次(預期結果)" />
        <input id="btnTest6" type="button" onclick="test5();" value="閉包多組多次(正确)" />
        <input id="btnClear" type="button" onclick="txtMsg.innerHTML = '';" value="清空" />
        <br />
        <textarea id="txtMsg" rows="2" cols="20" style="100%; height:600px;"></textarea>
    </body>
    </html>


    上面的代码关于“閉包多組多次(錯誤結果)”和“閉包多組多次(預期結果)”,红色字体结果都不是我预期的,还请教一下大家,感恩! 预期的结果应该是:

    =====================================
    閉包多組,每組都是新的並且組與組之間互不影響(預期結果)
    第一組,第一次:0
    第一組,第二次:1
    =====================================
    第二組,第一次:0
    第二組,第二次:1
    =====================================
    第一組,第三次:2
    第二組,第三次:3--->2(期望是2)
    =====================================
    閉包多組,每組都是新的並且組與組之間互不影響(錯誤結果)
    第一組,第一次:0
    第一組,第二次:1
    第一組,第三次:2
    =====================================
    第二組,第一次:0
    第二組,第二次:1
    第二組,第三次:2
    =====================================
    第一組,第四次:3
    第二組,第四次:4--->3(期望是3)

    -----------------------------------------------------------

    又仔细看了一边,真发现自己太粗心。

    直接this就搞定了,唉。

    人家明明写的:这时所有实例的type属性和eat()方法,其实都是同一个内存地址,指向prototype对象,因此就提高了运行效率。

    仔细思考应该可以认为:AddPkgErr中var intCount = 0;和AddPkgOK中AddPkgOK.prototype.intCount = 0;应该效果是一样的。

    参考资料:

    http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_encapsulation.html

  • 相关阅读:
    JDK源码分析 – HashMap
    牛哄哄的celery
    redis数据库基础篇
    RPC的入门应用
    Python的常用模块
    消息队列之真知灼见
    面向对象编程(2)
    python3的C3算法
    面向对象编程(1)
    CRM项目之stark组件(2)
  • 原文地址:https://www.cnblogs.com/chen110xi/p/5811492.html
Copyright © 2011-2022 走看看