【JavaScript】依赖循环下标的赋值操作

问题

如何正确进行对于依赖循环下标的赋值操作(形如 [i] = function() { /* use i */ }

描述

你有一个下标,你有一个函数,把它们合起来… 一般你会得到一堆错误…

为了能够顺利的避趋之,仅仅+1s是不够的,你需要更多的姿势…

真正的粉丝… 在代码运行前就能发现其中的Bug

为什么呢 Bug的第一个字母转90度试试…

代码

错误的姿势:

var arr = ['v1', 'v2', 'v3'];
for(var i = 0, funs = []; i < arr.length; ++i) {
    funs[i] = function() { console.log(arr[i]); };
}
funs.forEach(function(e) { e(); });

// 此时你渴望得到的结果是...(奶子!) 

// 依次输出v1 v2 v3 但其实结果是3个undefined

// 尝试一下输出 i; 你会发现此时 i=3; funs[3]是不存在的 所以结果为undefined

因为javascript的作用域规则导致i(坏…坏掉了)表现出奇怪的行为

此外还有一种比较常见的错误表现为,通过循环绑定的监听器触发的结果均为对最后绑定的监听器的触发行为

原因同上,当循环结束后i的值污染到了for循环外的作用域

为了杜绝这种现象的发生,你需要(去污粉!)借助一些手段…

正确的方法:

var arr = ['v1', 'v2', 'v3'];
for(var i = 0, funs = []; i < arr.length; ++i) {
    funs[i] = (function(i) { return function() { console.log(arr[i]); }; })(i);
}
funs.forEach(function(e) { e(); });

// 貌似一下子就复杂了起来... (我有什么办法呢 我也很绝望啊)

// 但结果打到了预期的目标 依次输出了v1 v2 v3

看上去很复杂,我们分解开看:
1. 首先确认我们需要返回的东西 function() { console.log(arr[i]); }
2. 该函数依赖循环下标,为了使下标i脱离当前作用域,独立绑定到每一个功能逻辑部分,你需要IIFE
3. (function(...args) { /* use args */ })(...args) 创建一个IIFE,传入需要脱离作用域的变量
4. 再其内部由于变量可见性,屏蔽了外部的同名变量,也就达到了改变指定变量作用域的作用

总结

使用 let 可以提早暴露这种问题,使用函数式思想也可以避免这种问题(我系map函数啦)

['v1', 'v2', 'v3'].map((e) => () => console.log(e)).forEach((f) => f());
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值