2017-08-26 76 views
0

的数组,我已经找到了解决办法这里由OhJeez:How to get an array of unique values from an array containing duplicates in JavaScript?JS返回由独特的阵列

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

我想问的是如何使代码的意义之上。我不明白的部分是,var如何保持它的关键。每次迭代都不会重置为空的散列/对象吗?

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

我的问题再一次是不应该每个迭代运行'var seen = {}'这一行?那么如何看待它的元素呢?

+2

可能重复[JavaScript关闭如何工作?](https://stackoverflow.com/questions/111102/how-do-javascript-closures-work) – Andreas

+0

[什么是(函数(){})( )构造在JavaScript?](https://stackoverflow.com/questions/8228281/what-is-the-function-construct-in-javascript) – Andreas

回答

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在其关闭。

+0

@DionChan如果有用,请接受此答案。 谢谢 –

0

这段代码是不必要的复杂,甚至会让经验丰富的JS程序员停下脚步一分钟,因为他们试图弄清楚它在做什么。它改写为

function filter() { 
    var seen = {}; 

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

的一点是,我们需要一个哈希(称为seen这里),并必须从某个地方申报。通常情况下,我们只是在适当的周围范围内声明它。无论出于什么原因,程序员都想避免这样做,所以他/他在传递给filter的函数中引入了另一个范围。正如我所说,这是令人困惑和不必要的。

+0

假设你的代码意味着函数过滤器(数组){...};我当然同意你的意思。但我仍然想知道为什么原始代码可以工作 –

0

在这里我们可以用两件事来解释这一点。

  1. JS是语言与功能可变范围,所以needed是可见的匿名函数内它被定义。
  2. 您可以看到作为参数array.filter的匿名自动执行功能正好用于管理变量范围并防止每次迭代都重置needed。该函数立即被调用,并且返回array.filter的实际回调,但在该回调的作用域中持续存在needed

匿名自执行函数是JS中的一个巨大工具。例如,您可以通过article了解更多信息。