最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - underscore's each checking for {} return of callback - Stack Overflow

programmeradmin1浏览0评论

I was examining how UnderscoreJS implements their each/forEach

//somewhere up top:
var breaker = {};

//then the each function
var each = _.each = _.forEach = function (obj, iterator, context) {
    if (obj == null) return;
    if (nativeForEach && obj.forEach === nativeForEach) {
        obj.forEach(iterator, context);
    } else if (obj.length === +obj.length) {
        for (var i = 0, l = obj.length; i < l; i++) {
            if (iterator.call(context, obj[i], i, obj) === breaker) return;
        }
    } else {
        for (var key in obj) {
            if (_.has(obj, key)) {
                if (iterator.call(context, obj[key], key, obj) === breaker) return;
            }
        }
    }
};

//iterator = callback
//context  = optional third parameter of each to provide context in the callback
//obj      = the list
//key      = key of the object (i for index when an array)

Basically, it's executing the callback for each item in the object/array. But this like confuses me

if (iterator.call(context, obj[key], key, obj) === breaker) return;

From what I understand, if the callback returns an object, the loop breaks, but... Why it's paring to breaker which is an internal object in the underscore module?. Doesn't it evaluate to false all the time since, even if the callback does return an object, it is always false since it's not the same object (therefore the loop never breaks). What's the reason behind this?

I was examining how UnderscoreJS implements their each/forEach

//somewhere up top:
var breaker = {};

//then the each function
var each = _.each = _.forEach = function (obj, iterator, context) {
    if (obj == null) return;
    if (nativeForEach && obj.forEach === nativeForEach) {
        obj.forEach(iterator, context);
    } else if (obj.length === +obj.length) {
        for (var i = 0, l = obj.length; i < l; i++) {
            if (iterator.call(context, obj[i], i, obj) === breaker) return;
        }
    } else {
        for (var key in obj) {
            if (_.has(obj, key)) {
                if (iterator.call(context, obj[key], key, obj) === breaker) return;
            }
        }
    }
};

//iterator = callback
//context  = optional third parameter of each to provide context in the callback
//obj      = the list
//key      = key of the object (i for index when an array)

Basically, it's executing the callback for each item in the object/array. But this like confuses me

if (iterator.call(context, obj[key], key, obj) === breaker) return;

From what I understand, if the callback returns an object, the loop breaks, but... Why it's paring to breaker which is an internal object in the underscore module?. Doesn't it evaluate to false all the time since, even if the callback does return an object, it is always false since it's not the same object (therefore the loop never breaks). What's the reason behind this?

Share Improve this question edited Jul 22, 2012 at 13:43 Joseph asked Jul 22, 2012 at 13:38 JosephJoseph 120k30 gold badges184 silver badges237 bronze badges 1
  • Another trick that I like, if you need to add values to the breaker objects is to instead create a Breaker class and use instanceof tests. – hugomg Commented Jul 22, 2012 at 13:52
Add a ment  | 

1 Answer 1

Reset to default 13

They use each internally for e.g. some. Since some does short-circuit, they can have each break there using the "secret" object, while not exposing this feature for regular users. They don't expose the break feature because the native function doesn't do that, either (so their shim is as native-like as possible). If they did, the break feature would only be available if the native function is unavailble, which isn't particularly helpful.

发布评论

评论列表(0)

  1. 暂无评论