javascript - 陷入实现闭包功能的困境 (javascript)

标签 javascript

作为一个 javascript 初学者,我以为我实现了 Closure 功能,直到看到 sample code 中的陷阱。以下。我尝试修改代码以弹出许多 C/C++/C#/Java 程序员期望的结果,

“项目1 1”

“项目2 2”

“项目3 3”

经过一小时的努力,我还是做不到。有哪位javascript高手可以教我如何修改吗?谢谢。

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]();
    }
}

testList();

最佳答案

这个想法是创建一个闭包,将其固定在其中。

  1. 您可以将 for 内容嵌套在立即函数中:

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

function testList() {
    var fnlist = buildList([1,2,3]);
    for (var j = 0; j < fnlist.length; j++) fnlist[j]();
}

testList();

这与编写其他函数相同:

function doStuff(k,arr,arr2){
    var item = 'item' + arr[k];
    arr2.push( function() {alert(item + ' ' + arr[k])});    
}

function buildList(list) {
    var result = [];
    for (var i = 0; i < list.length; i++) doStuff(i,list,result);
    return result;
}

function testList() {
    var fnlist = buildList([1,2,3]);
    for (var j = 0; j < fnlist.length; j++) fnlist[j]();
}

testList();

  • 使用最近的 forEach(value, index, array) 方法,会自动提供闭包:
  • function buildList(list) {
        var result=[];
        list.forEach(function(e){
            result.push(function(){alert('item'+e+' '+e)});
        });
        return result;
    }
    
    buildList([1,2,3]).forEach(function(e){e();});

    相当酷。

  • 使用 ECMAScript 6 let(感谢 elad.chen)
  • let 可以将 var 替换为循环中函数内的 i 作用域:不再需要像 (1) 和中那样创建闭包(2)。您只需将 item+list[i] 部分移动到函数内即可。但是 let 仅在严格模式下可用,并且 not in all browsers yet (例如,它仍然怀念 Firefox)

    'use strict'
    
    function buildList(list) {
        var result = [];
        for(let i=0;i<list.length;i++) {
            result.push(function(){alert('item'+list[i]+' '+list[i])});
        }
        return result;
    }
    
    function testList() {
        var fnlist = buildList([1,2,3]);
        for (var j = 0; j < fnlist.length; j++) fnlist[j]();
    }
    
    testList();

    关于javascript - 陷入实现闭包功能的困境 (javascript),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32667145/

    相关文章:

    javascript - 使用 CSS 重新排列/交织元素

    javascript - DIV onload 不触发 JavaScript 方法

    javascript - 如何在悬停时显示最近的 div?

    javascript - 如何使用 text() 查找元素

    javascript - 使用 PlacesService 反转地点 ID

    JavaScript - Express JS : chain promises not working/stopping at return keyword;

    javascript - JointJS - 主干错误无法读取未定义的属性 '_listenerId'

    javascript - 如何在Angular Js中设置输入框中日期的默认值

    javascript - 以网格形式放置 Bootstrap 指标

    javascript - 401 使用 POST 方法 API 身份验证失败