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

     完美解决。

  • 相关阅读:
    EF+MVC+Bootstrap 项目实践 Day7
    JS---数组
    OS---华硕笔记本从U盘启动安装系统
    PHP--分页类
    PHP--数据库操作类
    OS---net start mysql 发生系统错误5
    MYSQL---远程连接mysql数据库提示:ERROR 1130的解决办法
    CSS-小谈LV,HA!
    MYSQL---设置存储引擎
    MYSQL---存储引擎
  • 原文地址:https://www.cnblogs.com/mywy/p/6187174.html
Copyright © 2020-2023  润新知