javascript兼容问题 : let降级到var 遇到的闭包问题的解决方法
我用 for(let x in y) 循环一个图片元素数组。
for (let x in arr) { arr[x].onload = function(){ /* ... */ } }
这样写是没有问题的,因为:
for (let x...)的循环在每次迭代时都为x创建新的绑定。
...
在ES标准中,有一段是关于CreatePerIterationEnvironment,也就是for语句每次循环所要建立环境的步骤,里面有提及有关词法环境的相关步骤(LexicalEnvironment),这与使用let时会有关。所以,如果你使用了let而不是var,let的变量除了作用域是在for区块中,而且会为每次循环执行建立新的词法环境(LexicalEnvironment),拷贝所有的变量名称与值到下个循环执行。
...
但是 用 var 就不行了,因为运行环境没有更新,所以 onload 拿到的 [i] 每次都是最后一位。
相当于:
// 不需要加区块符,因为区块也不会影响 var i; i = 0; if (i < 10) setTimeout(()=>console.log("i:",i), 1000); i++; if (i < 10) setTimeout(()=>console.log("i:",i), 1000); i++; //...
拿怎么办呢?
在我一筹莫展的时候。 Babel 给了我答案。
原来的代码:
// _this : this(vue实例) for (let i in img_arr) { img_arr[i].onload = function () { origin_size_arr[i] = { width: this.width, height: this.height, } if (_this.img_calc_count === (img_arr.length - 1)) { _this.waterFullBFunc() } else { _this.img_calc_count++ } } }
Babel 降级之后:
var _loop = function _loop(i) { img_arr[i].onload = function () { origin_size_arr[i] = { width: this.width, height: this.height }; if (_this.img_calc_count === img_arr.length - 1) { _this.waterFullBFunc(); } else { _this.img_calc_count++; } }; }; // _this : this(vue实例) for (var i in img_arr) { _loop(i); }
以上。
参考:
posted on 2019-06-22 16:36 fox_charon 阅读(913) 评论(0) 编辑 收藏 举报