简体   繁体   English

return函数使用Closure返回数组值

[英]return function returns array values using Closure

I'm trying to use Closure in JS in order to declare a function named **expandArray()** which contain an Array named **myArray** and Returns an anonymous function that directly modifies myArray by increase the values by 1 than the returned function then returns the value of **myArray** . 我试图在JS中使用Closure以声明一个名为**expandArray()**的函数,该函数包含一个名为**myArray**的数组,并返回一个匿名函数,该函数直接通过将值增加1来修改myArray ,返回的函数然后返回**myArray**的值。 My Problem here one the last part where the returned function return a function not Array value ?! 我的问题在这里,最后一部分是返回的函数返回的函数不是数组值?

This is my code 这是我的代码

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

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

console.log(expandArray());

As its closure, you have invoked it only once like expandArray() , which return the function itself, which is below 作为其关闭,您只能像expandArray()一样调用它一次,它返回函数本身,位于下面

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

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

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

Ref: How do JavaScript closures work? 参考: JavaScript闭包如何工作?

You've written a function that returns a function when you run it: 您编写了一个函数,该函数在运行时返回一个函数:

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

So if you run expandArray() , it is going to return your anonymous function. 因此,如果您运行expandArray() ,它将返回您的匿名函数。 Exactly as you wrote it to do. 正是您编写的那样。

If you then want to get an actual reference to that internal myArray , you'll now need to actually run that returned function , so: 如果您随后想要获取对该内部myArray的实际引用,则现在需要实际运行该返回的函数 ,因此:

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

In your original code, you're only getting the return value of expandArray() , which is the function you're trying to use as a closure. 在原始代码中,您仅获得expandArray()的返回值,这是您尝试用作闭包的函数。 In order to get the closure's return value, try this out: 为了获得闭包的返回值,请尝试以下操作:

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

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

console.log(expandArray()());

The second set of parentheses after the call to expandArray() will invoke the closure and return the values you're seeking. 调用expandArray()之后的第二组括号将调用闭包并返回您要查找的值。

Just fyi, you are doing something very similar to the memoization pattern . 只是,您正在执行与记忆模式非常相似的操作。

To address your problem: as everyone else has already said, you return a function from expandArray . 解决您的问题:正如其他人已经说过的那样,您可以从expandArray返回一个函数。 What you want is to return the closed array (after incrementing every element). 您想要的是返回封闭的数组(在增加每个元素之后)。

To do this, you can use something called immediately-invoked function expression in combination with arrow functions to simplify your code: 为此,可以将称为立即调用函数的表达式与箭头函数结合使用以简化代码:

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

There are a couple of things incorrect with your code. 您的代码有些错误。

  • you can't change the values of variables declared within const. 您不能更改在const中声明的变量的值。 In the case of Objects and Arrays, you aren't allowed to assign a new reference with a new Array or Object. 对于对象和数组,不允许使用新的数组或对象分配新的引用。 We change the declarative operator to let instead of const . 我们将声明性运算符更改为let而不是const

  • myArray.map doesn't mutate myArray, it returns a new array based on the input from myArray and your passed in function that adds 1 to each value. myArray.map不会对myArray进行突变,它会基于myArray的输入和您传入的函数(每个值加1)返回一个新数组。 We can fix this by assigning myArray.map to the already declared myArray . 我们可以通过将myArray.map分配给已经声明的myArray来解决此问题。 That is to say, we're overwriting the old Array with a new one. 也就是说,我们正在用新阵列覆盖旧阵列。 This is why const in the above bullet point won't work. 这就是为什么上面的要点中的const不起作用的原因。

  • Your map function parameters are unnecessary The parameters for it that are most often used are the first two available, which is the item in the array and the index of that item. 不需要map函数参数。最常用的参数是前两个可用参数,它们是item in the arrayitem in the array以及该项目的index Since we're iterating over each number using map the function can simply return the item (declared as num in your code) plus 1. This will return a new array with your changed values. 由于我们使用map遍历每个数字,因此该函数可以简单地返回该item (在您的代码中声明为num )加1。这将返回具有更改后的值的新数组。 So we don't need the index at all.. 因此,我们根本不需要index

  • When you return a function from a function you need to invoke both to get the second return value. 从函数返回一个函数时,您需要同时调用这两个函数以获得第二个返回值。 When using a closure you need to keep a reference to the initial returned function. 使用闭包时,您需要保留对初始返回函数的引用。 This is confusing but if you think of it as levels - in your expandArray function you have two levels. 这很令人困惑,但是如果您将其视为级别-在expandArray函数中,您有两个级别。 The function itself and the function you're returning. 函数本身和要返回的函数。 when you call expandArray() you're invoking the first level, and making the second level available to be invoked, this is why expandArray() returns the second function and expandArray()() will return the value from the second function. 当您调用expandArray()您将调用第一级,并使第二级可被调用,这就是为什么expandArray()返回第二个函数, expandArray()()将返回第二个函数的值的原因。 We save the returned function in a variable called add_to_array by setting it equal to expandArray() , and then we consistently invoke add_to_array to return the new Array with the changed values. 通过将返回的函数设置为等于expandArray() ,将返回的函数保存在名为add_to_array的变量中,然后我们一致地调用add_to_array以返回具有更改后的值的新Array。

    • This is the most confusing part of closures, but what is happening is that the add_to_array variable is like a wedge in the function. 这是闭包最令人困惑的部分,但是正在发生的事情是add_to_array变量就像函数中的楔形。 It stops myArray from being deleted by the Browser because it requires the function to exist in the event that it needs to be invoked again. 它阻止myArray被浏览器删除,因为在需要再次调用该函数时,它要求该函数存在。 It's kind of like a bookmark in a book. 有点像一本书中的书签。 For the story to make sense whenever you open it, you don't just tear out the pages before the bookmark. 为了使故事在每次打开时都有意义,您不仅要撕掉书签之前的页面。 You keep the story intact because in five years when you come back to it you may need to read the previous pages at the bookmark to remember where you were. 您可以使故事保持原样,因为在回到故事的五年中,您可能需要阅读书签中的前几页以记住您的位置。 A closure works the same way. 闭包的工作方式相同。 It can't remove the variables from the initial expandArray function call because add_to_array is a placeholder in the middle of it. 它无法从最初的expandArray函数调用中删除变量,因为add_to_array是其中间的占位符。 The reference point keeps the book open. 参考点使书保持打开状态。 (for more info on closures you can check out this article here Destroying Buildings - A Guide to JavaScript Closures ) (有关闭包的更多信息,您可以在此处查看本文“ 销毁建筑物-JavaScript闭包指南”

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

Old post, but I still like to contribute. 旧帖子,但我仍然喜欢贡献。 I came up with this solution, as I think you want add something to the array instead of incrementing the numbers. 我想出了这个解决方案,因为我想您要向数组中添加一些内容而不是增加数字。

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

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM