2014-02-21 90 views
1
var any = _.some = _.any = function(obj, predicate, context) { 
    predicate || (predicate = _.identity); 
    var result = false; 
    if (obj == null) return result; 
    if (nativeSome && obj.some === nativeSome) return obj.some(predicate, context); 
    each(obj, function(value, index, list) { 
     if (result || (result = predicate.call(context, value, index, list))) return breaker; 
    }); 
    return !!result; 
    }; 

以上是在underscore.js中實現_.any方法。
在下面的行爲謂詞方法的結果進行測試時,爲什麼在這種情況下需要額外的檢查?

if (result || (result = predicate.call(context, value, index, list))) 

result是從一開始就false,並且當result變量是通過調用predicate功能設置爲true循環終止。所以在我看來,result變量的第一個檢查總是會評估爲false。爲什麼有這個變量的額外測試?

+0

結果可以在each()回調中隨時設置。如果結果不是虛假的,each()函數會盡早終止,就像真正的[] .some()那樣,下劃線將會關閉並放慢速度... – dandavis

+0

@dandavis結果只能由predicate.call()設置,否? – Yeonho

回答

2

,我發現這個GitHub上的問題由lshearer

當本地的forEach功能存在,如果_.any是帶一個 列表中的最後一個項目未通過真相測試 總是返回false(即使列表中的任何其他項目通過了 真相測試)。問題是本地forEach功能不會 短路(返回斷路器;對其沒有影響)。因此,調用_.any的 返回結果將被最後一個 項目覆蓋。

https://github.com/jashkenas/underscore/issues/177

如果你看看each實施它使用本地的forEach(如果可用)。

// The cornerstone, an `each` implementation, aka `forEach`. 
// Handles objects with the built-in `forEach`, arrays, and raw objects. 
// Delegates to **ECMAScript 5**'s native `forEach` if available. 
var each = _.each = _.forEach = function(obj, iterator, context) { 
    if (obj == null) return obj; 
    if (nativeForEach && obj.forEach === nativeForEach) { 
    obj.forEach(iterator, context); 
    } else if (obj.length === +obj.length) { 
    for (var i = 0, length = obj.length; i < length; i++) { 
     if (iterator.call(context, obj[i], i, obj) === breaker) return; 
    } 
    } else { 
    var keys = _.keys(obj); 
    for (var i = 0, length = keys.length; i < length; i++) { 
     if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return; 
    } 
    } 
    return obj; 
}; 

顯然,額外的檢查是必要的。

相關問題