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);
    

     完美解决。

  • 相关阅读:
    redhat yum替换成CentOS yum 并修改源
    C++11新特性实验
    常见的安装包制作程序installer
    如何在数据库中删除并添加唯一索引?
    springboot中的restTemplate工具类
    如何使用swagger(一)
    The POM for com.qingmu:entity:jar:1.0.0-SNAPSHOT is missing, no dependency information available
    java.lang.IllegalStateException: Found multiple @SpringBootConfiguration annotated classes
    在使用postman中配置返回html页面
    Springboot中设置返回数据的时间格式
  • 原文地址:https://www.cnblogs.com/mywy/p/6187174.html
Copyright © 2011-2022 走看看