javascript关闭后使用匿名函数 [英] javascript closure after using anonymous function

查看:127
本文介绍了javascript关闭后使用匿名函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力处理闭包,我知道在循环中,新函数使用迭代器的最后一个值来引用闭包

I'm working on closure so hard, and I know that in the loop, new function refer closure using the last value of the iterator

因此以下函数的结果是三次item3 undefined

so the following function's result is three times "item3 undefined"

function buildList(list) {
  var result = [];
  for (var i = 0; i < list.length; i++) {
    var item = 'item' + list[i];
    result.push( function() {alert(item + ' ' + list[i])} );
  }
  return result;
}

function testList() {
  var fnlist = buildList([1,2,3]);
  // using j only to help prevent confusion - could use i
  for (var j = 0; j < fnlist.length; j++) {
    fnlist[j]();
  }
} 

然后我知道匿名函数可以诱使范围,所以我编辑第一个函数为:

and then I know that anonymous function can induce scope, so I edit the first function as:

function buildList(list) {
  var result = [];
  for (var i = 0; i < list.length; i++) {
    (function(){
      var item = 'item' + list[i];
      result.push( function() {alert(item + ' ' + list[i])} );

    })();
  }
  return result;
}

但结果是item1 undefined,item2 undefined,item3 undefined,

but the result is "item1 undefined", "item2 undefined", "item3 undefined",

所以我的问题是,为什么在我使用范围后结果仍然未定义

so my question is, why is the result still undefined after I using scope?

推荐答案

假设这段代码的目的只是为了学习;你创建一个匿名函数,但你仍然指的是上一个作用域中的 i ,所以你不要改变任何东西从你最初写的第一个代码; i 仍然具有最后一个值( list.length )。

Assuming that the purpose of this code is just to learn; you create an anonymous function but you're still referring to the i in the previous scope, so you do not change anything from the first code you wrote initially; i still has the last value (list.length).

为了避免这种情况,您需要在您创建的函数范围内具有 i 的当前值:

In order to avoid that, you need to have the current value of i in the scope of the function you've created:

function buildList(list) {
  var result = [];

  for (var i = 0; i < list.length; i++) {
    var item = 'item' + list[i];
    result.push(function (index) { 
      return function() {alert(item + ' ' + list[index])}
    }(i));
  }

  return result;
}

也可以使用 bind ,以部分应用:

Alternatively you can use bind, to have partial application:

function buildList(list) {
  var result = [];

  for (var i = 0; i < list.length; i++) {
    var item = 'item' + list[i];
    result.push(function(index) {alert(item + ' ' + list[index])}.bind(null, i))
  }

  return result;
}

在ES6或启用JS 1.8.5的Firefox中,还可以声明块作用域变量:

In ES6, or in Firefox with JS 1.8.5 enabled, you can use also let that declares block scope variable:

function buildList(list) {
  var result = [];

  for (var i = 0; i < list.length; i++) {
    var item = 'item' + list[i];
    let index = i;
    result.push(() =>alert(item + ' ' + list[index]));
  }

  return result;
}



在上一个示例中还有 ES6箭头功能

这篇关于javascript关闭后使用匿名函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆