JS返回一个由唯一数组

时间:2017-08-26 07:20:49

标签: javascript arrays filter

我已经在OhJeez找到了解决方案:How to get an array of unique values from an array containing duplicates in JavaScript?

array.filter(function() {
  var seen = {};
  return function(element, index, array) {
    return !(element in seen) && (seen[element] = 1);
  };
}());

我想问的是如何理解上面的代码。我不明白的部分是var如何保持其密钥。不会将每次迭代重置视为空哈希/对象吗?

编辑:我想我理解闭包是如何工作的,这并不能解决我的问题。据我所知,Array.prototype.filter将数组的每个元素循环到回调函数,在本例中是匿名函数' var seen = {}; return函数(元素,索引,数组){return!(看到的元素)&& (见[element] = 1);};。这反过来又返回了里面的函数。

我的问题是,每次迭代都不应该运行' var seen = {}'?那怎么可以看到保留其元素?

3 个答案:

答案 0 :(得分:0)

这段代码是不必要的复杂,甚至会阻止经验丰富的JS程序员在他们试图弄清楚它在做什么的时候。将其改写为

function filter() {
  var seen = {};

  return array.filter(function(element, index, array) {
    return !(element in seen) && (seen[element] = 1);
  });
}

关键是我们需要一个哈希(在这里称为seen)并且必须在某处声明它。通常,我们只是在适当的周围范围内声明它。无论出于何种原因,程序员都希望避免这样做,因此他/她引入了传递给filter的函数的另一个范围。正如我所说,这是令人困惑和不必要的。

答案 1 :(得分:0)

我们可以用两件事来解释这个问题。

  1. JS是具有函数变量作用域的语言,因此needed在定义的匿名函数中是可见的。
  2. 您可以看作array.filter的参数的匿名自执行函数用于管理变量范围并防止每次迭代都重置needed。立即调用此函数,它返回array.filter的实际回调,但在此回调的范围内保持needed
  3. 匿名自执行函数是JS中的一个巨大工具。您可以从例如article中了解更多信息。

答案 2 :(得分:0)

array.filter(function() {
  var seen = {};
  return function(element, index, array) {
    return !(element in seen) && (seen[element] = 1);
  };
}());

您可以将其视为

var seen = {}
array.filter(function(element, index, array) {
    return !(element in seen) && (seen[element] = 1);
  })

两者将具有相同的输出仅差异变量在第一种情况下仍然是局部范围,这是好的。

当你调用array.filter()时,第一个参数是一个自调用函数,在传递给array.filter()之前进行求值;

所以它会使seen保持关闭状态。