zoukankan      html  css  js  c++  java
  • javascript的一点学习

    最近用vue.js用的很爽,在全栈开发的路上一路狂奔,发现后台跟前台一起确实更有意义。

    记录一个比较有意思的bug:

    目标是对一个全局的paramList进行json格式化显示。代码借鉴了 http://tool.oschina.net/codeformat/json

    for(var i = 0; i<_self.paramList.length; i++) {
      id = "#" + _self.paramList[i];
      console.log("___" + id) $(id).on("click", function () { console.log("**** id : " + id); _self.index = id.substring(1, id.length) console.log("new id :" + _self.index) var opt = { dom: "#preForParams" }; var jsonFormatter = new JsonFormater(opt); jsonFormatter.doFormat(js_source); $("#formParams").modal({ keyboard: true }); }); }

      

    这段代码在Vue.ready方法里调用,发现最后永远显示的paramList的最后一个元素的json格式化<pre>。

    在IDEA中有提示: mutable variable is accessible from closure.

    1. 尝试初始化一个全局变量temp,在onclick方法里面使用_self.temp,发现_self.temp还是固定的值。

    原因分析:在ready中代码已经执行完成,对那一时刻的状态而言,var i就是_self.paramList.length-1,所以每一个click时间注册都一list的最后一个数据为准,导致了bug产生 :(

    2. 在stackoverflow发现解释:

    The wrong way of using a closure inside a loop

    for(var i = 0; i < 10; i++) {
        setTimeout(function() {
            console.log(i);  
        }, 1000);
    }
    

    具体参考 http://bonsaiden.github.io/JavaScript-Garden/#function.closures

    这是javascript最重要的特性之一:闭包。

    One of JavaScript's most powerful features is the availability of closures. With closures, scopes always keep access to the outer scope, in which they were defined. Since the only scoping that JavaScript has is function scope, all functions, by default, act as closures.

    解决方案:

    solution 1: with anonymous wrapper

    for(var i = 0; i < 10; i++) {
        (function(e) {
            setTimeout(function() {
                console.log(e);  
            }, 1000);
        })(i);
    }
    

    solution 2: returning a function from a closure

    for(var i = 0; i < 10; i++) {
        setTimeout((function(e) {
            return function() {
                console.log(e);
            }
        })(i), 1000)
    }
    

    此方法体现了函数式编程的关键: 函数是一等公民。(意思是函数跟基本数据类型地位等同,computing 传入参数,得出结论。即只使用表达式,不使用语句。也就是说,每一步都是单纯的运算,而且都有返回值。)

    最终,采取了第一种solution,代码如下:

    (function(e,v) {
        $(e).on("click", function () {
            console.log("**** id : " + e);
            _self.index = e.substring(1, e.length)
            console.log("new id :" + e)
            var opt = {
                dom: "#preForParams"
            };
            var jsonFormatter = new JsonFormater(opt);
            jsonFormatter.doFormat(v);
            $("#formParams").modal({
                keyboard: true
            });
        });
    })(id, js_source);
    

     完美解决。

  • 相关阅读:
    Attributes.Add用途与用法
    Reapter控件中更换Td背景色
    SQL SERVER查询时间条件式写法
    C# Cache何时使用及使用方法
    C#中Cache用法
    用sql语句将两个时间相减,得到时间距的DateDiff()函数
    HTML5 带进度条的异步文件上传原理
    Node环境Grunt开发流
    HTML5的Web SQL Databases(html5 本地数据库)API
    移动端范围拖动选择效果
  • 原文地址:https://www.cnblogs.com/mywy/p/6187174.html
Copyright © 2011-2022 走看看