2014-03-14 72 views
2

我正在學習underscore.js和javascript編程。 雖然我看到下劃線的來源,但我無法理解它的某些部分。爲什麼'_.negate'用法在'underscore.js'中使用'this'參數?

我不明白爲什麼它使用'this'在_.negate中,因爲其他部分接收'上下文並使用它們。 以下是源代碼。

https://github.com/jashkenas/underscore/blob/master/underscore.js

_.negate = function(predicate) { 
    return function() { 
     return !predicate.apply(this, arguments); 
    }; 
}; 

在使用_.negate的地方是在_.reject和_.omit。 查看_.reject的代碼,它接收'上下文'並將其用於上下文。

_.filter = _.select = function(obj, predicate, context) { 
    var results = []; 
    if (obj == null) return results; 
    if (nativeFilter && obj.filter === nativeFilter) { 
     return obj.filter(predicate, context); 
    } 
    each(obj, function(value, index, list) { 
     if (predicate.call(context, value, index, list)) results.push(value); 
    }); 
    return results; 
}; 



_.reject = function(obj, predicate, context) { 
    return _.filter(obj, _.negate(predicate), context); 
}; 

請給我一些解釋。 在此先感謝。

+0

in'_.reject'過濾器函數接收上下文作爲第三個參數否定只接收謂詞 –

回答

3

apply呼叫同時做兩件事情:

  1. 它設置this將生效裏面predicate
  2. 它將匿名函數的參數列表直接傳遞到predicate,而不必關心正在使用多少個參數。

(2)應足夠清楚,如果你知道在JavaScript約arguments; arguments是一個類似數組的對象,它包含函數的當前參數列表,JavaScript中的所有函數都是可變的(儘管他們的定義是這樣說的),而當你不知道有多少個函數時,你是如何處理這些參數的。

(1)應該清楚地看看如何使用_.negate返回值。裏面_.filter,該predicate調用使用call

predicate.call(context, value, index, list) 

這將thiscontextpredicate。如果predicate實際上是_.negate(original_predicate)那麼這是有效的:

var f = function() { 
    return !original_predicate.apply(this, arguments); 
}; 
f.call(context, ...) 

所以original_predicate將調用像original_predicate.apply(context, arguments)和指定this(即context)將獲得時生效original_predicate執行。

如果_.negate只是這樣做:

return function(a, b, c) { 
    return !predicate(a, b, c); 
}; 

然後兩個壞的事情會發生:

  1. 指定context將丟失。
  2. 只有三個參數可以通過。這對於_.filter來說是足夠的,但可能不適用於_.negate的其他用途。

失去跟蹤的context將打破很多代碼,使用Function.prototype.apply指定this恰好解決了參數列表的問題是免費的。

+0

感謝您的親切解釋。現在我明白它正常工作。 :) –

相關問題