我已经在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 = {}'?那怎么可以看到保留其元素?
答案 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)
我们可以用两件事来解释这个问题。
needed
在定义的匿名函数中是可见的。array.filter
的参数的匿名自执行函数用于管理变量范围并防止每次迭代都重置needed
。立即调用此函数,它返回array.filter
的实际回调,但在此回调的范围内保持needed
。 匿名自执行函数是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
保持关闭状态。