2016-07-08 101 views
3

我一直在尝试理解这个功能很长一段时间,但它对我来说没有意义。该函数的目标是删除与其他参数号匹配的参数数组中的任何数字。Javascript:请帮我理解这个功能

为什么需要对该数组进行切片以使其正常工作?

args.splice(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); 
+0

@Rayon,它是[1,1] –

+0

是的,输出是没有额外参数的传递数组,如OP所述。在这种情况下,没有2和3. –

+0

我花了一段时间才得到你的问题。原因很简单:来自'args'的第一个参数总是被忽略,因为'objects'是相等的('==='用于' indexOf')只有当他们被引用.... – Rayon

回答

4

让我们通过它逐行:

var args = Array.prototype.slice.call(arguments); 

JavaScript的arguments变量是类似于数组,但它不是一个数组。你可以自己试试这个:arguments instanceof Array会给出错误的。因此,从Array原型应用slice方法将简单地将arguments转换为真实数组。

args.splice(0, 1); 

这是去除第一个参数,这是你的情况arr

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

这将通过在arr所有的数字和将检查他们中的每一个,如果它在参数存在。当indexOf()返回-1时,表示在该数组中找不到该元素。

+0

但它没有'args .splice' ... –

+0

当然,它的工作原理。由于第一个参数是一个数组,因此您将比较数字与始终返回false的数组。因此,在实践中,如果保留第一个参数或将其删除,则无关紧要。但删除第一个参数更为正确。 –

+0

这非常有帮助。谢谢! – Oli

0

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

拿这个例子

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 
0

我已添加评论,请查看它是否有助于您理解该功能。

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); 

请参考下面的文档阅读有关参数对象在此函数中使用:

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/arguments

0
  1. 过时参数[数组[6],2,3]
  2. 拼接或删除参数的第一个元素后的参数[2,3]
  3. 因此闭合函数过滤元素存在于其他两个元素的第一个元素中。只返回[1,1]
0

要了解发生了什么事情,我们需要了解Function.prototype.call method

调用您传递给它的第一的说法,在这种情况下是神奇的JS arguments objectArray.prototype.slice方法,然后在传递什么理由跟进。

因此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 +实现与spread operator,所以你可以写:

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

arr我们将有[1,2,3,1,2,3]和 在args我们将有[[1,2,3,1,2,3],2,3] arr上的过滤函数循环如果element不在参数中,则和args.indexOf(element)将返回-1。 所以,在循环第一次元素的值是1和内部环

args.indexOf(1)返回-1,因为1不存在在args因为在0索引我们有阵列和在第一索引我们有2,在第二个索引中,我们有3个。所以条件=== -1为真,并返回1到要打印到控制台的数组。

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