V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
coolicer
V2EX  ›  JavaScript

[_.js] 尝试读一些JS库加强文化知识,有个地方不懂。

  •  
  •   coolicer · 2013-07-22 14:13:28 +08:00 · 3063 次点击
    这是一个创建于 4175 天前的主题,其中的信息可能已经有所发展或是发生改变。
    var each = _.each = _.forEach = function(obj, iterator, context) {
    if (obj == null) return;
    if (nativeForEach && obj.forEach === nativeForEach) {
    //如果是数组,使用数组原生的forEach
    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)) { // _.has 判断 属性/方法 是否来自该对象,不会检查到原型链上
    if (iterator.call(context, obj[key], key, obj) === breaker) return;
    }
    }
    }
    };

    就是这句不懂,这个的breaker是一个对象,看不透这个句...
    if (iterator.call(context, obj[key], key, obj) === breaker) return;

    这代码的格式哪去了?
    10 条回复    1970-01-01 08:00:00 +08:00
    yyfearth
        1
    yyfearth  
       2013-07-22 14:16:48 +08:00
    要格式你得用gist
    coolicer
        2
    coolicer  
    OP
       2013-07-22 14:18:54 +08:00
    @yyfearth 用gist,然后呢?贴过来?
    chchwy
        3
    chchwy  
       2013-07-22 14:27:55 +08:00
    [V2EX技巧] 贴图和贴代码的方法
    http://www.v2ex.com/t/74249
    coolicer
        4
    coolicer  
    OP
       2013-07-22 14:36:37 +08:00
    @chchwy soga。我懂了
    livelazily
        5
    livelazily  
       2013-07-22 15:46:52 +08:00
    breaker 是用来中断循环的,但ECMAScript 5中的forEach是不能中断循环的,这里这么写估计是为了以后方便中断循环而预留的接口
    otakustay
        6
    otakustay  
       2013-07-22 16:10:51 +08:00   ❤️ 1
    ES5的forEach是不能中断的,但_的某些方法依赖这个forEach又要求使用中断这个特性,那怎么办呢?_的办法是,让forEach的iterator返回一个特殊的值,这个值除非是自己内部的函数,其它函数是不可能造得出来的,然后判断是这个值就中断。而创建这么个“特殊的值”的最好的办法就是,随便声明一个对象,因为任意2个对象不会相等,所以在闭包里放一个对象,外部拿不到闭包里的这个对象,就安全了,这个对象就叫breaker
    coolicer
        7
    coolicer  
    OP
       2013-07-22 16:18:36 +08:00
    @livelazily
    @otakustay

    原来如此,这里还有这样的学问。
    coolicer
        8
    coolicer  
    OP
       2013-07-22 16:21:25 +08:00
    @otakustay 我那些注释没错吧,那这样,后面两个else的东西不用执行了?难道还会进if里执行iterator.call(context, obj[i], i, obj) ?
    otakustay
        9
    otakustay  
       2013-07-22 16:26:49 +08:00
    注释没错,如果有原生forEach,确实不会用到_自己实现的,也不会用到breaker,这里存在不一致性

    不过_用到breaker的方法是这些:every、all、some、any,这几个的特点是用了breaker提早中断有性能优势,不用也不会影响正确性(性能劣势被原生forEach的速度挽回来了,大概)

    于是breaker就这么用着了
    coolicer
        10
    coolicer  
    OP
       2013-07-22 16:32:13 +08:00
    @otakustay 明白了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5437 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 07:28 · PVG 15:28 · LAX 23:28 · JFK 02:28
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.