return函数使用Closure返回数组值

时间:2018-07-27 16:17:07

标签: javascript ecmascript-6

我正在尝试在JS中使用Closure,以便声明一个名为**expandArray()**的函数,其中包含一个名为**myArray**的数组,并返回一个直接修改 myArray 的匿名函数。通过将值比返回的函数增加1,然后返回**myArray**的值。我的问题在这里,最后一部分是返回的函数返回的函数不是数组值?!

这是我的代码

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 :(得分:3)

作为其闭包,您只能像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?

答案 1 :(得分:1)

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

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

因此,如果您运行expandArray(),它将返回您的匿名函数。完全像您写的那样。

如果您随后想要获得对该内部myArray的实际引用,则现在需要实际运行返回了函数的 ,因此:

var getMyArray = expandArray();
var result = getMyArray();
console.log(result);

答案 2 :(得分:1)

在原始代码中,您仅获得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()());

调用expandArray()之后的第二组括号将调用闭包并返回您要查找的值。

答案 3 :(得分:1)

仅供参考,您所做的事情与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)

您的代码有些错误。

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

  • myArray.map不会突变myArray,它会基于myArray的输入以及您传入的函数(每个值加1)返回一个新数组。我们可以通过将myArray.map分配给已经声明的myArray来解决此问题。也就是说,我们正在用新阵列覆盖旧阵列。这就是为什么上述要点中的const无法正常工作的原因。

  • 您的map函数参数不是必需的。最常用的参数是前两个可用参数,即该项目的item in the arrayindex。由于我们使用map遍历每个数字,因此该函数可以简单地返回item(在您的代码中声明为 num )加1。这将返回一个包含以下内容的新数组您更改的值。因此,我们根本不需要index

  • 从函数返回一个函数时,您需要同时调用这两个函数以获得第二个返回值。使用闭包时,您需要保留对初始返回函数的引用。这很令人困惑,但是如果您将其视为级别-在expandArray函数中,您有两个级别。函数本身和要返回的函数。当您调用expandArray()时,您正在调用第一级,并使第二级可被调用,这就是expandArray()返回第二个函数而expandArray()()将从第二个函数返回值的原因。第二功能。通过将返回的函数设置为等于add_to_array,将返回的函数保存在名为expandArray()的变量中,然后我们一致地调用add_to_array以返回具有更改后的值的新Array。

    • 这是闭包最令人困惑的部分,但是发生的是add_to_array变量就像函数中的楔形。它阻止myArray被浏览器删除,因为它要求函数在再次需要调用时存在。有点像一本书中的书签。为了使故事在每次打开时都有意义,您不仅要撕掉书签之前的页面。您可以使故事保持原样,因为在回到故事的五年中,您可能需要阅读书签中的前几页以记住您的位置。闭包的工作方式相同。它无法从最初的expandArray函数调用中删除变量,因为add_to_array是中间的占位符。参考点使书保持打开状态。 (有关封包的更多信息,您可以在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 :(得分:0)

旧帖子,但我仍然想贡献。我想出了这个解决方案,因为我想您要向数组中添加一些内容,而不是增加数字。

function expandArray() {
    let myArray = [1, 1, 1];

    return function() {
        myArray.push(1)
        return myArray
    }
}

const array = expandArray();
const result = array();
console.log(result)