2016-07-08 98 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