Javascript:请帮助我理解这个函数

Javascript:请帮助我理解这个函数,javascript,arrays,Javascript,Arrays,我试图理解这个函数已经有一段时间了,但它对我来说毫无意义。函数的目标是删除参数数组中与其他参数号匹配的任何数字 为什么需要对数组进行切片才能使函数工作 参数拼接(0,1)是否冗余?我把它拿走了,什么也没变 看起来过滤函数完成了大部分工作,但我不知道它实际上是如何过滤数字的 function destroyer(arr) { var args = Array.prototype.slice.call(arguments); args.splice(0, 1); return arr.f

我试图理解这个函数已经有一段时间了,但它对我来说毫无意义。函数的目标是删除参数数组中与其他参数号匹配的任何数字

为什么需要对数组进行切片才能使函数工作

参数拼接(0,1)是否冗余?我把它拿走了,什么也没变

看起来过滤函数完成了大部分工作,但我不知道它实际上是如何过滤数字的

function destroyer(arr) {
  var args = Array.prototype.slice.call(arguments);
  args.splice(0, 1);
  return arr.filter(function(element) {
    return args.indexOf(element) === -1;
  });
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);

切片不会改变。它返回原始数组中元素的浅层副本。原始数组的元素被复制到返回的数组中

就拿这个例子来说

var object = {
'0': 'zero',
'1': 'one',
'2': 'two',
'3': 'three',
'4': 'four',
length: 5
};
var sliced = Array.prototype.slice.call( object, 3 );
 ['three','four']; //output

让我们一行一行地看一下:

var args = Array.prototype.slice.call(arguments);
JavaScript的
参数
变量类似于数组,但它不是数组。您可以自己尝试:
参数数组的instanceof
将给出false。因此,应用数组原型中的
slice
方法只需将
参数
转换为实际数组

args.splice(0, 1);
这是为了删除第一个参数,在您的案例中是
arr

return arr.filter(function(element) {
  return args.indexOf(element) === -1;
});

这将遍历
arr
中的所有数字,并检查每个数字是否存在于参数中。当
indexOf()返回-1时,表示数组中找不到元素。

我添加了注释,请查看它是否有助于理解函数

function destroyer(arr) {
  // arr just holds [1, 2, 3, 1, 2, 3]
  var args = Array.prototype.slice.call(arguments);
  // args contains nested array with all input params [[1, 2, 3, 1, 2, 3], 2, 3]
  args.splice(0, 1);
  //args is spliced and we have [2,3] in args
  //Filter arr=[1, 2, 3, 1, 2, 3] elements, condition it must not be in args i.e [2,3]
  return arr.filter(function(element) {
    return args.indexOf(element) === -1;
  });
}

destroyer([1, 2, 3, 1, 2, 3], 2, 3);
有关此函数中使用的对象参数,请参阅以下文档:

  • passe参数[Array[6],2,3]
  • 拼接或删除参数的第一个元素后的参数[2,3]
  • 所以闭包函数将数组的第一个元素中存在的元素和其他两个元素一起过滤。只返回[1,1]

  • 要了解发生了什么,我们需要了解

    它在传递给它的第一个参数上调用
    Array.prototype.slice
    方法,在本例中是神奇的JS,然后传入后面的任何参数

    因此,
    Array.prototype.splice
    是不必要的,您只需编写:

    function destroyer(arr) {
      var rest = Array.prototype.slice.call(arguments, 1);
      return arr.filter(function(element) {
        return rest.indexOf(element) === -1;
      });
    }
    
    事实上,这已通过在ES2015+中实现,所以您可以编写:

    function destroyer(arr, ...rest) {
      return arr.filter(function(element) {
        return rest.indexOf(element) === -1;
      });
    }
    

    arr
    中,我们将有
    [1,2,3,1,2,3]
    和 在
    args
    中,我们将有[[1,2,3,1,2,3],2,3] arr上的滤波函数环 如果
    element
    不在args中,则indexOf(element)
    将返回-1。 因此,在循环中元素值第一次为1,在循环中为1

    args.indexOf(1)返回-1,因为args中不存在1,因为在0索引处有数组,在第一索引处有2,在第二索引处有3。因此,条件==-1为真,并将1返回到要打印到控制台的数组


    对于下一个元素,即arr中的2,语句args.indexOf(2)返回存在2的第一个索引,即args数组中的1。同样地,整个循环将为
    arr

    @Rayon执行,它是[1,1]是的,输出是传递的数组,没有额外的参数,如OP所说。在那种情况下,没有2和3。我花了一段时间才明白你的问题。。原因很简单:
    参数
    中的第一个参数总是被忽略,因为
    对象
    是相等的(
    ==
    仅在
    索引中使用,如果它们被引用的话…。所以无论你拼接还是不拼接,因为没有任何东西是
    ==
    该项,它被过滤…@GerardoFurtado–没有任何东西等于
    对象
    ,除非它们被引用。。。因此,
    数组
    被简单过滤
    =
    只是解释
    indexOf
    是如何工作的。是的,当然可以。因为第一个参数是一个数组,您将把数字与一个总是返回false的数组进行比较。因此,在实践中,保留或删除第一个参数并不重要。但删除第一个论点更为正确,这非常有帮助。非常感谢。