代码之家  ›  专栏  ›  技术社区  ›  Fahad AlDaferi

返回函数使用闭包返回数组值

  •  1
  • Fahad AlDaferi  · 技术社区  · 7 年前

    我试图在JS中使用闭包来声明一个名为 **expandArray()** 其中包含一个名为 **myArray** 并返回一个匿名函数,该函数直接修改 肌阵 通过将值比返回的函数增加1,然后返回 ** MyLax** . 我这里的问题是最后一部分,返回的函数返回的是函数而不是数组值?!

    这是我的密码

    function expandArray() {
      const myArray = [1, 1, 1];
    
      return function () {
        myArray.forEach( function (num, index, myArray) {
            myArray[index] = num + 1;
        });
        return myArray;
      };
    }
    
    console.log(expandArray());
    
    6 回复  |  直到 7 年前
        1
  •  1
  •   Mike 'Pomax' Kamermans    7 年前

    您已经编写了一个函数,该函数在运行时返回一个函数:

    function expandArray() {
      const myArray = [...];
      // return this when we run expandArray():
      return function() {
        ...
      }
    }
    

    所以如果你跑 expandArray() ,它将返回匿名函数。就像你写的那样。

    如果你想得到一个实际的内部参考 myArray ,您现在需要实际运行 返回的函数 因此:

    var getMyArray = expandArray();
    var result = getMyArray();
    console.log(result);
    
        2
  •  3
  •   Shushanth Pallegar    7 年前

    作为它的闭包,您只调用过一次 expandArray() ,返回函数本身,该函数位于

    ƒ () {
        myArray.map( function (num, index, myArray) {
            myArray[index] = num + 1;
        });
        return myArray;
      }
    

    you need to invoke it again to get your result back 如下

    expandArray()() //[2, 2, 2]
    

    裁判: How do JavaScript closures work?

        3
  •  1
  •   FK82    7 年前

    仅供参考,您正在做与 memoization pattern .

    为了解决您的问题:正如其他人已经说过的,您从 expandArray . 您需要返回关闭的数组(在增加每个元素之后)。

    为此,您可以使用 immediately-invoked function expression 结合箭头函数简化代码:

    const expandArray = (() => {
      const myArray = [1, 1, 1];
      
      return () => {
        myArray.forEach((num, index) => {
          myArray[index] = num + 1;
        });
        
        return myArray;
      };
    })();
    
    console.log(expandArray());
    console.log(expandArray());
    console.log(expandArray());
        4
  •  1
  •   zfrisch    7 年前

    您的代码有一些不正确的地方。

    • 不能更改常量中声明的变量值。对于对象和数组,不允许使用新的数组或对象分配新的引用。我们将声明运算符改为 let 而不是 const .

    • myArray.map 不改变myarray,它根据输入返回一个新的数组 myArray 以及传递给每个值加1的函数。我们可以通过分配 MyARAY.MAP 到已声明的 肌阵 . 也就是说,我们正在用新数组覆盖旧数组。这就是为什么 康斯特 在上面的要点不起作用。

    • 你的 map 函数参数是不必要的。最常用的参数是前两个可用参数,即 item in the array 以及 index 那个项目的因为我们用 地图 函数可以简单地返回 item (宣布为 号码 在代码中)加1。这将返回一个具有更改值的新数组。所以我们不需要 指数 完全。。

    • 当您从一个函数返回一个函数时,您需要调用这两个函数来获取第二个返回值。使用闭包时,需要保留对初始返回函数的引用。这是令人困惑的,但如果你把它看作是层次——在你的 expandArray 函数有两个级别。函数本身和返回的函数。当你打电话 expandArray() 您正在调用第一级,并使第二级可供调用,这就是为什么 扩展数组() 返回第二个函数和 expandArray()() 将从第二个函数返回值。我们将返回的函数保存在一个名为 add_to_array 等于 扩展数组() 然后我们不断地调用 Addiotox数组 返回具有更改值的新数组。

      • 这是闭包中最令人困惑的部分,但是发生的是 Addiotox数组 变量就像函数中的一个楔子。它停止了 肌阵 不会被浏览器删除,因为它需要在需要再次调用时存在函数。有点像书中的书签。为了让这个故事在你打开的时候有意义,你不只是在书签前撕掉页面。你要保持故事的完整性,因为五年后当你回到它的时候,你可能需要在书签上阅读之前的页面来记住你在哪里。闭包的工作原理是一样的。它不能从初始值中删除变量 扩展阵列 函数调用是因为 Addiotox数组 中间是一个占位符。参考点使书保持打开状态。 (有关闭包的更多信息,请参阅本文 Destroying Buildings - A Guide to JavaScript Closures )

    function expandArray() {
      let myArray = [1, 1, 1];
    
      return function () {
        myArray = myArray.map( function (num) {
           return num + 1;
        });
        return myArray;
      };
    }
    
    let add_to_array = expandArray();
    console.log( add_to_array(),add_to_array(),add_to_array() );
        5
  •  1
  •   hcs    7 年前

    在原始代码中,您只获得 expandArray() ,这是您试图用作闭包的函数。要获取闭包的返回值,请尝试以下操作:

    function expandArray() {
      const myArray = [1, 1, 1];
    
      return function () {
        myArray.forEach( function (num, index, myArray) {
            myArray[index] = num + 1;
        });
        return myArray;
      };
    }
    
    console.log(expandArray()());
    

    调用后的第二组括号 扩展数组() 将调用闭包并返回正在查找的值。

        6
  •  0
  •   Imran Khan    7 年前

    旧的职位,但我仍然喜欢贡献。我提出了这个解决方案,因为我认为您需要向数组中添加一些内容,而不是增加数字。

    function expandArray() {
        let myArray = [1, 1, 1];
    
        return function() {
            myArray.push(1)
            return myArray
        }
    }
    
    const array = expandArray();
    const result = array();
    console.log(result)