将参数传递给filter()

时间:2015-10-28 05:12:06

标签: javascript

我有一个函数,它接受一个数组,然后是一些参数。在该函数中,我想在数组上使用filter()方法,但我想使用参数[i]。举个例子:

function destroyer(arr) {
  var test = arr.filter(function(value){
    return value != arguments[1];
  });
  return test;
}

console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));

调用参数[1]并没有给我我想要的东西,因为我猜测匿名函数有自己的参数,filter()正在使用。我想到的一个解决方案是创建一个数组并将参数复制到该数组。但我想知道是否有办法将参数传递给过滤器?我知道过滤器有一个thisArg值,但我不知道如何使用它来得到我想要的东西。

编辑:我尝试使用谷歌搜索解决方案,大多数解决方案涉及使用绑定或应用。但是,我找不到与filter()或类似方法直接相关的任何内容,如forEach,reduce,map等。我尝试使用“this”作为thisArg值,但这似乎没有做任何事情。我已经尝试过使用bind并应用它,但我似乎无法获得正确的语法。

1 个答案:

答案 0 :(得分:0)

如果您有权访问ES6环境,则可以使用“spread parameters”(...)来表示可变长度参数列表。除了箭头函数和Array#includes之外,您的代码可能非常紧凑:

function destroyer(arr, ...destroy) {
  return arr.filter(value => !destroy.includes(value));
}
  

我有一个有效的解决方案(将参数复制到数组中),但我更想知道如何将参数传递给filter()以更好地理解filter()和其他类似方法的工作原理。

您无需将参数传递给filter() 。可以在过滤器回调的范围内简单地提供参数。但是,arguments很特别;它指的是当前函数的参数。没有办法引用其他函数的参数,例如外部函数。因此,除了保存外部函数中不同变量名称(例如args)下的参数之外别无选择;那么你可以在回调中引用那个变量,因为回调“关闭”了那个变量。

如果你真的想要将要销毁的数字列表“传递”到内部函数,而不是让它通过引用在外部作用域中创建的变量来访问它们,那么是的,理论上你可以使用thisArg

function destroyer(arr/*, number to destroy*/) {
  return arr.filter(do_not_destroy, arguments);
                                    ^^^^^^^^^ PASS thisArg
}

现在我们可以将do_not_destroy定义为

function do_not_destroy(elt) {
  return [].slice.call(this, 1).indexOf(elt) === -1;
                       ^^^^ REFER TO thisArg (arguments)
}

请注意这里的两件事。首先,我们将参数列表称为this,因为我们使用filter将它们传递给thisArg。其次,我们不能写this.slice...,而必须写[].slice.call(this...,因为this是一个参数对象,它不是一个“真正的”数组而没有slice方法

要使do_not_destroy独立于其参数是一个特殊参数对象的事实,在开头有一个额外参数(数组),我们可以转换为destroyer内的数组功能:

function destroyer(arr/*, number to destroy*/) {
  return arr.filter(do_not_destroy, [].slice.call(arguments, 1));
}

现在我们可以将do_not_destroy定义为

function do_not_destroy(elt) {
  return this.indexOf(elt) === -1;
}

但现在我们基本上回到了我们开始的地方。仅通过让内部函数(回调)引用外部作用域中的变量集而不是“传递”要忽略的值列表,我们使用后门thisArg机制将它们传递给回调。我真的没有看到这一点。