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

反对 try{}catch (e){}的进来, B 君已经是全群公敌!

  •  
  •   minggeJS · 2015-12-28 23:25:18 +08:00 · 19616 次点击
    这是一个创建于 3042 天前的主题,其中的信息可能已经有所发展或是发生改变。
    (提醒:我不是来问问题的,我已经有自己答案!)
    A 君和 B 君各自用 JS 做一个简单的需求:

    function test(foo){
    var obj= new foo();

    obj.wo.ok.arr.push("帅哥");

    return obj;


    }

    当 foo 传入错误参数时 程序是肯定是报错的! obj.wo 无法索引到时,也同样是报错的
    现在 A 君和 B 君分别采用不同的方法
    -------------------------------------------------------------
    A 君采用的方法是:

    function test(foo) {
    if (typeof foo == "function") {
    var obj = new foo();
    if (obj.wo && obj.wo.ok && Object.prototype.toString.call(obj.wo.ok.arr) == "[object Array]") {
    obj.wo.ok.arr.push("帅哥");
    return obj;
    }
    }
    return false;
    }
    ----------------------------------------------------------------------------------------
    B 君采用的方法是:
    function test(foo) {
    try{
    var obj = new foo();
    obj.wo.ok.arr.push("帅哥");
    return obj;
    }catch (e){}
    return false;
    }



    结果 B 君成为了全群公敌,及取笑的对象, A 君和 B 君各不相让, A 君更是大骂 B 君:“你百度看看看,你用 TRY 是菜鸟的行为, TRY 效率很差的,应该尽量避免使用 TRY ”。
    B 君一向按自己的原则做事, B 君不相信百度,坚持自己的 TRY 立场,B 君觉得自己的 TRY 用得完全合理,一气之下愤然离群!

    现在问大家:上面两段你觉得 A 君和 B 君的代码 谁的效率最高呢!
    (稍后公布答案)!
    第 1 条附言  ·  2015-12-29 17:45:02 +08:00
    第 2 条附言  ·  2015-12-29 18:10:19 +08:00
    @jarlyyn A 君 B 君代码只是一个演试效果,我并没有说用 try 就不能用 if 了,我从头到尾没这样说

    在实际开发中, B 君可以 TRY 再配合适当 if 进行判断, 而 A 君呢,只能 IF 又再多 if 一句。
    最后 A 君的代码,变得又长又没有效率,而 B 君的代码大不了再多一句 if 。一样是轻巧型代码

    所以到最后 B 君始终是最后胜利者
    第 3 条附言  ·  2015-12-30 18:41:38 +08:00
    retun false 只是为了让演试具有立体效,为何要捉住 retun false 不放!何必呢

    function test(foo) {
    try{
    var obj = new foo();
    obj.wo.ok.arr.push("帅哥");
    return obj;
    }catch (e){
    return "我要 DEBUG :"+e
    }

    }
    210 条回复    2016-01-15 23:45:58 +08:00
    1  2  3  
    Zzzzzzzzz
        101
    Zzzzzzzzz  
       2015-12-29 18:00:36 +08:00
    还是我来翻吧.
    hustlzp
        102
    hustlzp  
       2015-12-29 18:01:16 +08:00
    我来翻
    hustlzp
        103
    hustlzp  
       2015-12-29 18:01:26 +08:00
    我来翻页
    hustlzp
        104
    hustlzp  
       2015-12-29 18:01:41 +08:00
    啊啊啊啊啊啊啊啊啊翻页君来了
    VmuTargh
        105
    VmuTargh  
       2015-12-29 18:04:07 +08:00
    @hustlzp 这也可以翻页也真是醉了
    hustlzp
        106
    hustlzp  
       2015-12-29 18:05:47 +08:00
    @VmuTargh 回复了没反应,搞得我多回了几条...
    VmuTargh
        107
    VmuTargh  
       2015-12-29 18:07:17 +08:00
    @hustlzp 要是我没屏蔽帖子里面某个**家伙的话,我这边估计早就翻页了
    behappy
        108
    behappy  
       2015-12-29 18:10:41 +08:00
    我支持 jarlyyn 。
    就算 catch ,也只应该 catch 空指针异常。
    usb
        109
    usb  
       2015-12-29 18:23:18 +08:00
    !!!!!!!!!!!!!!!
    Kilerd
        110
    Kilerd  
       2015-12-29 18:41:40 +08:00
    实力歪楼。

    楼主的言语才粗鲁,没有看下去的耐心。

    慎交(我对自己说)。
    theohateonion
        111
    theohateonion  
       2015-12-29 18:50:53 +08:00
    我是 minggejS 作者!这句强有力的话震颤到了我
    HarryZD
        112
    HarryZD  
       2015-12-29 19:09:01 +08:00
    不觉得 try{} catch(e) {} 这种,和 goto 差不多嘛,有点随意改变执行流的赶脚
    testlc
        113
    testlc  
       2015-12-29 19:20:50 +08:00
    @Kilerd +1
    Automan
        114
    Automan  
       2015-12-29 19:32:21 +08:00
    特来膜拜一下
    johnhsm2333
        115
    johnhsm2333  
       2015-12-29 19:55:28 +08:00
    总感觉好像明哥说什么就是什么的样子
    coldfog
        116
    coldfog  
       2015-12-29 20:01:42 +08:00
    我赌两块钱楼主是 B
    oubushixb
        117
    oubushixb  
       2015-12-29 20:04:44 +08:00
    评论比文章好看...
    holyzhou
        118
    holyzhou  
       2015-12-29 20:36:06 +08:00
    哈哈 我就是堆个楼的
    sorra
        119
    sorra  
       2015-12-29 21:50:24 +08:00
    然而你没有测试 false 的情形
    lizhenda
        120
    lizhenda  
       2015-12-29 22:15:42 +08:00
    还是看回复精彩
    falcon05
        121
    falcon05  
       2015-12-29 22:25:24 +08:00 via iPhone
    喜闻乐见
    mzer0
        122
    mzer0  
       2015-12-29 23:12:27 +08:00   ❤️ 6
    @msg7086
    @sorra
    @HarryZD
    @leeyuzhe
    @msg7086
    @Tink
    @leeyuzhe
    @jarlyyn
    @behappy
    @mko0okmko0
    @saber000
    @minggeJS

    我为今天早些时候的言论表示抱歉.

    --------------------------------------------------------------------------------------------------------------------------------

    1. 我不讨论 false 返回值的问题, 也不讨论 try-catch 在这里用合适不合适, 我只是说明一点: 有使用 try-catch 来优化 if-else 的技巧, 并且这种技巧很常用, 这也是 C++的惯用技巧. JS 不追求性能, 所以很多人可能对这种技巧不是很了解. 我想说明的是, 如果你不懂得这种技巧, 那你在这个问题上就没有发言权. 使用 try-catch 来优化 if-else 只能在非常特定的情形下用, 编程模型也和 if-else 的不一样. 使用 try-catch 以后, 返回值怎么办, 应不应该在非异常的情形下使用 try-catch, 这些问题都有很多很多文章来解释 /辩论. 这个技巧在上个世纪 C++刚被发明的时候就吵得热火朝天, 现在的一致意见是: 如果要使用 try-catch 来优化 if-else, 那必须保证函数之外的代码不受影响.

    * 我并不是来这里吵"try-catch 比 if-else 好还是坏", 我只是说明, 有这种技巧的存在, 并且被广泛使用. 题注给的信息很少, 所以我不能判断在这种情形下该不该用 try-catch 来优化, 也不是说所有的 if-else 都能这样做, 我只是简单地阐述这是一种技巧.

    * 如果你是写前端的, 而你不懂得这种技巧, 那么你可以学习一下, 而不是说看到这种自己没见过的用法, 就轻易否认.

    --------------------------------------------------------------------------------------------------------------------------------

    2. 如果 mingge 贴出来的代码没错的话, A 的写法其实"很幼稚". CPU 在分支预测的时候, 总是倾向于预测 then 的那一支, 因此:

    if (obj.wo && obj.wo.ok && Object.prototype.toString.call(obj.wo.ok.arr) == "[object Array]") {
    obj.wo.ok.arr.push("帅哥");
    return obj;
    }

    这样的写法是低效率的, 这样会导致 CPU 总是预测到 NULL 指针的情形, 应该这样写:

    if (obj.wo || obj.wo.ok || Object.prototype.toString.call(obj.wo.ok.arr) != "[object Array]") {
    return false;
    }

    obj.wo.ok.arr.push("帅哥");
    return obj.

    这样, CPU 就会倾向于预测 obj.wo.ok.arr.push("帅哥"); 的那一支.

    * 所以说, 在不考虑 A 和 B 代码规范的情况下(毕竟代码规范是个信仰问题), A 的代码效率很低, 计算机基础知识薄弱......

    --------------------------------------------------------------------------------------------------------------------------------

    3. 这里, 我要黑 @minggeJS . 我对 @minggeJS 的 JS 水平不做评价, 但我必须告诉你, 你做的实验是完全错误的. 你做的实验并不能表明, try-catch 的效率优于 if-else, 因为在你的情形下, 解析器可能会直接把你实验中 try-catch 的代码优化为 i += 20000000 , 而 if-else 的代码则不做优化, 老老实实跑完 20000000 次. 解析器对 try-catch 是用专门的优化的, 我举个例子:

    for(...) { try...catch } 很可能会被优化为 try { for(...) } catch

    在 C++的情形下, 百分之百会被优化为后者.

    --------------------------------------------------------------------------------------------------------------------------------

    最后说一句, 用 try-catch 来优化 if-else 需要很高的编程水平, 对汇编与异常处理有着深刻的了解, 才能够这样做. 如果你真的不懂, 你就说不懂, 但你不能否认这种技巧. 我也不是说 mingge 就懂, 因为我也没看到他具体写的代码, 我只是就事论事.
    razrlele
        123
    razrlele  
       2015-12-29 23:21:34 +08:00 via iPhone
    真心希望无论是 G 站还是 V 站会有越来越多像 @mzer0 这样的前辈。
    msg7086
        124
    msg7086  
       2015-12-29 23:23:38 +08:00
    @minggeJS 笑了,我又没说你在误导,我说楼上有很多帖子在误导。
    当然你自己喜欢跳进坑来我也拦不住。

    上面我的帖子里既没有谈效率也没有谈代码量,你连我说的是哪个点都不知道就跳出来说我口气大。
    我上面说的几点是写代码时通行的原则,并不局限于 JS ,也适合其他语言和环境。
    已知错误用判断,未知错误用异常,最后代码会非常好维护,也便于写测试。
    对于企业来说,效率算个鸟?代码量算个鸟?
    写出不好维护的代码,后期维护的投入就是几十万几百万的成本。
    相比起多部署几十台服务器或者多招几个人来写你说的「又长又花时间的代码」来说,维护的成本高得多。

    不信?
    我们公司现在就有六七万行基于异常处理的代码。
    随便不小心点错的东西就是异常异常异常。
    点个功能哪里出了问题就是异常异常异常。
    Debug ?几百个一锅端风格的异常处理代码你慢慢搜去吧。
    我们核算过,这点代码全部整理完至少需要 200 万到 300 万美金的成本。

    还有测试驱动开发呢,考虑到测试的代码量最少也要和程序代码量相当来看,估计你会觉得写测试是多么的「又长又花时间」吧。
    可惜对于企业来说这是最省钱的方案,一套系统只要多花几十万美金的钱投在人工上就可以省下几百万美金。

    (我不知道你有多少编程经验,所以我不妄加评论你的水平。
    如果你觉得自己很厉害,看不上别人,这是你的自由。

    你开心就好。)
    qnnnnez
        125
    qnnnnez  
       2015-12-29 23:26:58 +08:00 via iPhone
    @mzer0 NULL 空指针是什么类型的异常?我只知道读写 nullptr 会引发一个段错误,然后它会被包装成一个 C++异常。本文讨论的 JS 中是没有指针概念的;变量动态绑定到值,所以无法判断变量所绑定的值的类型。 C++里编译器会帮你检查,根本不存在你说的什么空指针问题,而 A 的做法和编译器的做法是类似的,只是运算移动到了运行期,确实可能产生效率问题。
    如果让我来写,我会详细地写出注释和文档,然后不考虑异常。
    msg7086
        126
    msg7086  
       2015-12-29 23:31:21 +08:00
    @mzer0 你说的这个有些道理。
    不过这里的优化我觉得不应该是人来做,也不应该是 CPU 来做,而应该是编译器负责。
    很多现代化的编译器都有 Profiling ,通过输入一个比较真实的数据集来模拟真实的运行情况,在其中分析分支的命中率,微调汇编代码。
    比如你说的 if then 分支预测命中问题,如果编译器发现 then 的一侧比 else 一侧遇到的概率少,那么编译器就可以手调汇编代码,交换两段代码的位置,提高运行效率。
    另外微调效率的时候还要考虑很多别的因素,比如 SIMD 时候的 prefetch 间隔等等,这些都是要专业的人员通过仔细的 CPU pipeline profiling 才能优化到极限。

    只用上面两个例子其实很难说明有数量级级别的差异的。
    就算是 C++桌面程序,一个登录过程是花费 10ms 还是 20ms 其实真的没区别。
    mzer0
        127
    mzer0  
       2015-12-29 23:35:38 +08:00
    @msg7086 无论你说多少, 你都不能掩盖这样一个事实: A 完全不知道分支预测理论......

    @qnnnnez 所以我说了, 要看具体对异常的处理. 在 Java 或者 JS 这样的语言中, 也有"空指针异常"这个概念, 但是和 C++里的"空指针异常"概念是不一样的. "空指针异常"实际上是操作系统定义的, 与具体编程语言无关.
    qnnnnez
        128
    qnnnnez  
       2015-12-29 23:38:02 +08:00 via iPhone
    @msg7086 js 的 jit 编译器应该不会做到这种地步吧(只是猜测)
    mzer0
        129
    mzer0  
       2015-12-29 23:39:44 +08:00
    @qnnnnez 就算 JS 是有 GC 的, 区别也不是很大. 如果对象不是一个多态, 或是泛型, 那么同样会触发空指针异常, 只不过异常是交由 GC 处理而已. 如果是多态或者泛型, 那么可能内置有 if 来检查空指针.

    不要忘记, Java 的引用本质上也是一个指针, 只不过把指针封装了一下而已.
    mzer0
        130
    mzer0  
       2015-12-29 23:43:15 +08:00
    @qnnnnez 最后补充一下. 空指针异常是操作系统定义的, 因为内存映射是由操作系统来做的. 空指针异常不是由任何一门编程语言来定义的, 而是操作系统自有的概念.

    不知者无畏. 不要因为自己懂得少, 就认为有乱说话的资本.

    睡了. 不再回复这个帖子任何内容.
    qnnnnez
        131
    qnnnnez  
       2015-12-29 23:43:51 +08:00 via iPhone
    @mzer0 我原本以为读写空指针指向的地址引发的错误就是"空指针异常"了,麻烦你告诉我 Windows 对"空指针异常"的定义
    msg7086
        132
    msg7086  
       2015-12-29 23:48:32 +08:00
    #127 @mzer0 我的回复里没有提到 A 或者 B 的水平如何。
    A 君知不知道分支预测理论我完全不得知。
    同样 B 君我也不知道他是否就是「真的懂」而不是「凭直觉」或者「 I'm lovin' it 」。
    所以不妄加评论。

    一开始我就说了,具体怎么用要看上下文场景,抛开场景空谈程序没有太大的意义。
    话要说完整才行,说话只说一半只会误导迷茫的新人后来者。
    更何况上面的效率是在说 JS 而不是在说 C++。
    具体的 JS 执行情况更还要依赖各大浏览器的脚本引擎才行。
    说不定前后两个版本的引擎之间的性能都是不一样的。

    #128 @qnnnnez 抱歉 JS 我不太熟。
    这里可以邀请一发 @otakustay 菊苣,他可能会知道详细内幕。
    minggeJS
        133
    minggeJS  
    OP
       2015-12-29 23:49:18 +08:00
    @mzer0
    你比 A 君还要厉害啊
    if (obj.wo || obj.wo.ok || Object.prototype.toString.call(obj.wo.ok.arr) != "[object Array]") {
    return false;
    }

    你确定没有问题!!! obj.wo 为 null 然后 obj.wo.ok 执行, obj.wo.ok 马上报错了,我草了,牛 B 啊
    msg7086
        134
    msg7086  
       2015-12-29 23:51:35 +08:00   ❤️ 1
    #130 @mzer0 顺便一提,这里是论坛,人人都有发言的自由,只要内容不是粗话脏话不是反动反 D ,都可以说。
    不知者无谓,说出来以后大家讨论才能互相学习到知识。
    不说出来永远也不知道自己是对是错。

    不要因为自己懂得多,就认为有不让人说话的资本。
    你不是 Tu 共。
    qnnnnez
        135
    qnnnnez  
       2015-12-29 23:53:16 +08:00 via iPhone
    @mzer0 行行行, js 里, java 里,底层实现发现有了个随便什么异常,就写
    *reinterpret_cast<int*>(nullptr)=0;
    然后 cpu 去访问,发现该页不可写,然后中断,然后操作系统捕获,然后 crt ( libc ?)捕获,然后…最后被异常处理程序捕获
    受教了
    minggeJS
        136
    minggeJS  
    OP
       2015-12-29 23:53:34 +08:00
    @mzer0 写代码动一下脑啊

    if (obj.wo || obj.wo.ok || Object.prototype.toString.call(obj.wo.ok.arr) != "[object Array]") {
    return false;
    }

    造成笑话的 obj.wo || obj.wo.ok 索引不到, obj.wo.ok 已经报错了,牛 B 得厉害

    大家来观摩
    jarlyyn
        137
    jarlyyn  
       2015-12-29 23:53:46 +08:00
    @minggeJS
    @mzer0

    不想多说什么了。

    在 js 的领域谈分支预测,何必呢?

    js 的程序。性能不是消耗在 dom 重绘,就是耗费在等待异步回调上了。

    祝楼主的 JS 库早日取代 jQuery,也祝另一位仁兄的加密数据库早日成功。毕竟我这种人没什么前途,也没什么创意,早晚被淘汰。

    最后,有句话还是忍不住。

    Javascript 虽然名字里有 Java ,但真的和 Java 没啥关系的,没必要拉 Java 进来躺枪。
    minggeJS
        138
    minggeJS  
    OP
       2015-12-30 00:01:06 +08:00
    @mzer0 我作为五年 JS 开发经验,我也写 C 和 DELPHI 的,很客气的跟你说,你的理论全部是错的。

    if (obj.wo || obj.wo.ok || Object.prototype.toString.call(obj.wo.ok.arr) != "[object Array]")

    你看那句,大哥,报错了,看到了没!报错啦 ! 你是新手入门吧
    df4VW
        139
    df4VW  
       2015-12-30 00:09:55 +08:00
    本来挺支持明哥的,现在看看还是有必要上高中和大学

    基本的技术什么的说实话不是傻逼多写几年都能会,但做人什么的,真的是需要积累的
    minggeJS
        140
    minggeJS  
    OP
       2015-12-30 00:15:04 +08:00
    @df4VW 小朋友,那你注定读死书了! 不要浪费爹妈的钱,学习成绩不好,早点回家种田,不要浪费父母的钱
    df4VW
        141
    df4VW  
       2015-12-30 00:53:53 +08:00
    @minggeJS 明哥你好,我确实是农村出生的,小时候也配父母双抢三枪过。上大学之后没花过父母钱,硕士来美国半奖读的,现在在美国编程。让您失望了,希望您的后代能不浪费你辛苦赚来的钱,成绩不好的话,我可以教他种田
    raincious
        142
    raincious  
       2015-12-30 00:54:31 +08:00   ❤️ 1
    @msg7086 和 @mzer0 两位大神都来了。我个渣渣也来凑个热闹。

    @msg7086 所说关于不应该使用异常来控制程序流的说法是在大部分时候都是正确的,异常应该用在可能发生且需要就地处理错误的时候,而不是作为一种优化手段。

    http://c2.com/cgi/wiki?DontUseExceptionsForFlowControl
    http://programmers.stackexchange.com/questions/189222/are-exceptions-as-control-flow-considered-a-serious-antipattern-if-so-why
    http://stackoverflow.com/questions/1018800/performance-of-c0x-exceptions
    http://mortoray.com/2013/09/12/the-true-cost-of-zero-cost-exceptions/
    http://www.shanekirk.com/2015/06/c-exceptions-the-good-the-bad-and-the-ugly/

    其实 @mzer0 也提到了“**这种** try-catch 的用法”,按我理解应该是针对“指向空指针”这个特定“异常”时的(会比较高效)用法。但 ReferenceError 是不是等同于 NullPointerException 是有疑问的。更何况 JavaScript 解析器如何处理 try...catch block 和其他语言是否一样也不好说。建议各位深入研究下一些 JavaScript 的解析和执行器然后再做分享会更有说服力。
    shyling
        143
    shyling  
       2015-12-30 00:57:33 +08:00 via iPad
    AB 两类人就不评价了。
    个人觉得。如果不是特别关注整条路径的连续执行的话用 B 简单明了一点。
    因为 aa.b 也可能是调用 aa 中 b 的 getter 方法呀。
    假如像这样的一个过程 io('xxx).connect.readandparse.closeandreturn.push('yyy')
    如果是 A 那不就重复操作咯。。
    好吧,我完全不知道自己在说什么
    msg7086
        144
    msg7086  
       2015-12-30 01:22:50 +08:00
    @shyling 你这个例子是比较典型的适合 try/catch 的做法。
    楼主举的例子其实也是比较典型的 try/catch 。

    比如有这样一个函数

    checkUserCredential(user) {
    rec = db.findUser(user.name)
    return this.checkPassword(rec, user.password)
    }

    这里 user.name / user.password 适合用 if 判断; rec 两者都可以; db 连接情况适合用异常处理。
    因此:

    checkUserCredential(user) {
    showError if (!user.name || !user.password)
    try {rec = db.findUser(user.name)} catch databaseError {log('database connection error')}
    showError if (!rec)
    return this.checkPassword(rec, user.password)
    }

    以上代码都是伪代码,不代表任意的实际环境,不代表 JavaScript 情况。
    latyas
        145
    latyas  
       2015-12-30 02:16:53 +08:00
    个人觉得代码的表意性更重要。

    就像总有人扯 python 的性能不好,但是又不敢说自己永远用 C 写代码
    keithsun80
        146
    keithsun80  
       2015-12-30 09:24:35 +08:00
    我觉得 B 比较简单直观, 至于性能...反正扔到客户端, 这块代码看起来慢一点也无伤大雅, 代码可读性, 日后维护重于某观念(不要用 try catch 来做什么什么)

    但我不喜欢 MingGe 为人, @powtop 快点把他打飞..!
    XadillaX
        147
    XadillaX  
       2015-12-30 09:26:50 +08:00 via Android   ❤️ 1
    其实 A 没有任何侮辱。

    只是拿了 JSPerf 的测试结果给他看。

    然后 B 急了,说不信这个测试『软件』——注意,说是测试『软件』。

    还有 B 原话才是带有人身攻击性的。

    不要问我为什么知道,因为那个群是芋头的群,我也在里面。

    http://ww4.sinaimg.cn/large/a15b4afegw1ezhfeyyibij20hs0vk0un
    XadillaX
        148
    XadillaX  
       2015-12-30 09:27:35 +08:00 via Android
    @livid 图片解析错误。
    XadillaX
        149
    XadillaX  
       2015-12-30 09:29:30 +08:00 via Android
    在说完上面的话之后 B 君自己退群了,然后去自己的 ISSUE 里面和这里歪曲事实宣扬。
    yeqiu
        150
    yeqiu  
       2015-12-30 09:34:16 +08:00
    我一般这么写,看了楼上讨论这么多,我突然觉得微软大腿真粗

    try
    {

    }
    catch (NullReferenceException)
    {

    }
    catch (IndexOutOfRangeException)
    {

    }
    catch (Exception)
    {

    throw;
    }
    keithsun80
        151
    keithsun80  
       2015-12-30 09:57:52 +08:00
    @XadillaX 求图片
    wadahana
        152
    wadahana  
       2015-12-30 10:01:26 +08:00
    @HarryZD goto 可是好东西, linux kernel 里面 一堆的 goto
    c/cpp if-else 的分支预测有__builtin_expect, 再不济也可以嵌入__asm 手动调优?还真没见过这样的理由用 try catch
    lwbjing
        153
    lwbjing  
       2015-12-30 10:03:24 +08:00
    擦,一天没上 V 站,就搞到这种程度了...
    enda
        154
    enda  
       2015-12-30 10:04:46 +08:00
    我是来围观明哥的
    xuewl
        155
    xuewl  
       2015-12-30 10:05:55 +08:00
    我只说一点,楼主的 github 上 README.md 文件能不能注意下排版,让我感觉不是你英文有问题,而是语文有问题。
    visonme
        156
    visonme  
       2015-12-30 10:46:10 +08:00
    很少用 try-catch 的飘过,原因不同于 AB 君,仅仅是一种喜好
    denghongcai
        157
    denghongcai  
       2015-12-30 10:53:44 +08:00
    @mzer0 这里是短路判断……你这样是想多了,反而会造成异常
    Exin
        158
    Exin  
       2015-12-30 11:08:25 +08:00 via iPhone
    《讨论的艺术》
    MiguelValentine
        159
    MiguelValentine  
       2015-12-30 11:09:09 +08:00
    @denghongcai 其实处理器预测分支只和 j 系指令有关系,预测循环只和 loop 系指令有关系, node 套了双层谁知道最后指令已经被翻译成什么样了是吧= =毕竟它效率应该是汇编的 2.5%以下。
    ryd994
        160
    ryd994  
       2015-12-30 11:22:00 +08:00
    @mzer0 “ CPU 在分支预测的时候, 总是倾向于预测 then 的那一支”
    这个不一定的吧,现代 CPU 都应该动态预测了,如果分支预测出错,预测器会相应调整的啊。对于重复执行的代码,开始的那几次基本可以忽略的啊。
    同时 JS 作为动态语言, C++的经验是否适用,是个问题。
    我还是学生,请多赐教。

    我同意你说的,不能一概而论。两种做法自有长短。
    而且,如果一开始算法就错了,那纠结这半点点的性能,毫无意义。

    @minggeJS " 我的观点是无论可信源也好,不可信源也好,都应该尽可能地使用 try 回错,因为效率快,代量码少 "
    简单的一句 try ,确实方便,但掩藏了多少问题?有些明明是应该向上传递,由上层处理的异常,也被你全部抢下来,那照你这么说,我其实只需要在最外层套一个 try ,里面有错没错,不管什么都往外扔好了。
    这样的风格我不是不用,但主要用于保护用户界面,如果用户看见 exception ,用户既不明白什么意思,也不知道该怎么做。所以 catch 下来给用户一个友好的反馈。但仅此最外层一行。其他的 catch 必定有明确的类型,明确的用途,而且范围尽可能小。
    我 JS 写的不多,但对于静态编译的语言,我一般是 if 过滤用户输入, assert 过滤内部调用(调用者应当保证调用合法)。这样调试的时候用 assert 协助解决问题,发布的时候可以去掉 assert 。

    关于读书有没有用,我的看法:读书不能造就大师,规范化教育最大的意义在与让三流才能的人作出二流的工作。因此,读过书的人,至少是二流。没读过书的人,要么是大神,要么根本不入流。与应试教育无关,这是我在美国学习最大的体会。我自学编程也算是小有心得,但看见周围同学仅凭 4 年的学习,也可以写出多少像样的代码。尽管其中大部分人永远都摸不到一流程序员的门槛,但还是要感叹一下学校教育的威力。
    songco
        161
    songco  
       2015-12-30 12:27:00 +08:00
    这种东西不说应用场景就是耍流氓
    Garwih
        163
    Garwih  
       2015-12-30 12:42:58 +08:00
    @Livid 图片解析有问题,上图链接:
    ww4.sinaimg.cn/large/a15b4afegw1ezhfeyyibij20hs0vk0un
    xgfan
        164
    xgfan  
       2015-12-30 12:53:00 +08:00   ❤️ 2


    V 站感觉又陷入了一种类似的“政治正确”,这货就是个傻逼,技术过得去就不是傻逼了?
    msg7086
        165
    msg7086  
       2015-12-30 13:03:14 +08:00
    #149 @XadillaX 我估摸着你说的这些大家都知道了……
    一个人的为人,只要三言两语就能看出来了,多说无益。
    imdoge
        166
    imdoge  
       2015-12-30 13:08:21 +08:00
    @xgfan ……这人
    gemchen
        167
    gemchen  
       2015-12-30 13:35:06 +08:00
    今天老夫算是开了眼了(指 minggejs)

    ps: 这样使用 trycatch 是很经典的,不存在错误的问题,但是影响代码可读性,大型合作项目是不太建议这么干的。
    zhangegcn
        168
    zhangegcn  
       2015-12-30 13:35:29 +08:00
    凑个热闹。这么多人这是要上天啊?
    Immortal
        169
    Immortal  
       2015-12-30 13:38:11 +08:00
    代码是一回事 做人也是一回事啊
    真刺激
    ipconfiger
        170
    ipconfiger  
       2015-12-30 13:51:56 +08:00
    e, JS 下不是一个 callback 就让 try catch 变渣了么?
    jarlyyn
        171
    jarlyyn  
       2015-12-30 14:00:50 +08:00
    @gemchen

    catch 所有错误然后 return false 确定不存在错误问题么?
    hqdmy
        172
    hqdmy  
       2015-12-30 14:13:36 +08:00
    @mzer0 学习了~
    gemchen
        173
    gemchen  
       2015-12-30 14:40:49 +08:00
    @jarlyyn

    Brian Kernighan :计算机编程的本质就是控制复杂度

    lz 举得例子不太合适,忽略潜在的错误直接 return false 当然是不合理的

    我是说用某些情况下 trycatch 代替简单重复的 if 没问题,也很常见
    aivier
        174
    aivier  
       2015-12-30 14:57:28 +08:00
    不同情况不同做法,有些时候真的不需要多余判断,如果这个错误在某些场景下不会造成什么严重后果,又不会导致什么功能损失,那直接用 try catch 也没什么,偏要写个复杂的判断也不是不可以
    jarlyyn
        175
    jarlyyn  
       2015-12-30 15:12:45 +08:00
    @gemchen

    如果不忽略潜在的错误,一样需要在 try catch 里放一堆 if 或者 case,那楼主的立场不也没有了。

    从我的角度来看, try catch 代替 if 本来就是个伪命题。能被 try catch 代替的 if 判断,大部分本来就是被误用的 IF 罢了。

    以楼主的这个例子的 A 来看,是在接口的定义时预定了可以有其他人性的数据传入,只不过在这种情况下返回个特值而已。

    从我的经验和从事的工作来看。运行效率远没有开发和维护效率高。是判断的就应该用判断,该抛错误的就应该抛。

    个人觉得,毫无理由的替代不过是给别人挖坑,给自己挖坑。
    benjycui
        176
    benjycui  
       2015-12-30 15:59:32 +08:00
    想起了之前写的一个东西 https://github.com/benjycui/exist.js#existinvokeobj-nestedmethod

    不过碰到这种情况,应优先考虑优化数据结构。
    rungo
        177
    rungo  
       2015-12-30 16:31:24 +08:00
    @xgfan 图片里面的 2 段代码,这是测鬼吧。
    OldRyan
        178
    OldRyan  
       2015-12-30 17:06:30 +08:00   ❤️ 1
    什么明哥,就一个哗众取宠的小丑,情商真够底下的,一眼看去逼格满满,实则脑残一个,要是跟同事相处时这种态度,完全没人愿意去叼他。工作写出这种代码如何跟同事配合,效率?这代码能提高多少效率?电脑那么高的运行速度执行代码起来,人类能察觉出来差了多少吗。半桶水就在这里 BB ,真是够了,怎么现在还没被打死,也只是在网上做个键盘侠很厉害吧?
    keithsun80
        179
    keithsun80  
       2015-12-30 17:07:00 +08:00
    @xgfan 求群号码, 最近在看 React, 最好私信, 我担心群满了我进不去
    lbxl2345
        180
    lbxl2345  
       2015-12-30 17:14:39 +08:00
    这个帖子真的好火,很多大神发表了自己的意见,但似乎明哥并没有耐心去讲道理,看到好多 V 友被喷,这实在是让人对他的印象大打折扣呢!
    DemoJameson
        181
    DemoJameson  
       2015-12-30 17:15:34 +08:00
    @minggeJS 拜托你自己也动一下脑啊,人家就是写漏了个 ! 号,根据上下文很明显可以推断出来。

    if (!obj.wo || !obj.wo.ok || Object.prototype.toString.call(obj.wo.ok.arr) != "[object Array]") {
    return false;
    }
    minggeJS
        182
    minggeJS  
    OP
       2015-12-30 17:52:55 +08:00
    @DemoJameson

    写少一个!号,错就错,程序会原谅你写!号,整个语句报错就是报错

    还有: if (!obj.wo || !obj.wo.ok

    我面试看到这样的语句,直接就让他滚蛋,为什么呢?
    语句肯定要顺着走才快 if (obj.wo &&obj.wo.ok ,偏要在前面再加一个!号,程序又慢一截!obj.wo
    这叫没事找事的入门新手,思维迟纯的所为
    kedron
        183
    kedron  
       2015-12-30 17:54:16 +08:00
    其实这个问题可以通过一个简单的常识来解决。任何编程语言中,所谓 XX 绝对不能用的说法肯定是错误的,除非是有 bug ,否则人家设计这个功能,肯定是有适合的使用场景的。关键是什么时候用,怎么用的问题。
    minggeJS
        184
    minggeJS  
    OP
       2015-12-30 18:05:00 +08:00
    @jarlyyn 关于你所说的 getter 问题,请 你说中要点

    var foo=function(){
    Object.defineProperty(this,'wo',{get:function(){return realWOValue(this);}});
    };

    foo.prototype={
    wo:{ok:{arr:[1 , 2]}}
    }

    function test(foo) {
    try{
    var obj = new foo();
    obj.wo.ok.arr.push("帅哥");
    return obj;
    }catch (e){}
    return false;
    }

    alert(test(foo));//成功 false


    没发现你所说的现象,请 你说中要点
    wenzichel
        185
    wenzichel  
       2015-12-30 18:12:01 +08:00
    @minggeJS 你很好的抓住了非重点,人家的本意只是表明“ CPU 在分支预测的时候, 总是倾向于预测 then 的那一支”,因此更应该在 then 的分支执行代码。结果你逮着人家忘写非的符号,喷了半天
    minggeJS
        186
    minggeJS  
    OP
       2015-12-30 18:12:54 +08:00
    @XadillaX A 君 没有直接骂我,但是对我使用了软暴力,他叫群主踢我,还说我是 SB ,叫别人不要理我,还肿拥群友一起攻击,完全不讨论技术,对我实施严重软暴力,在这种情况下,我自尊受创,使用了硬暴力,问候了他。我不是雷锋,我也有脾气,我也一名凡人,当面对攻击时,我一样会反击!

    任何事情你都要给我一个说法,你不给我说法,我给你说法 ----------选自:杨佳杀 JC 被判死刑前名言
    jarlyyn
        187
    jarlyyn  
       2015-12-30 18:23:50 +08:00
    @minggeJS

    重点就是不该 return false,呵呵。
    minggeJS
        188
    minggeJS  
    OP
       2015-12-30 18:29:44 +08:00
    return false 只是告诉你操作失败了,当然你可以不加 return XXXX, 顶多返回 undefined 出来,
    有时候为了让演试更加立体点 , 我特意加上去的!

    catch ( e ) 里的 e 一样可以捕捉到你所要的数据
    ragnaroks
        189
    ragnaroks  
       2015-12-30 18:40:37 +08:00
    说个笑话,js 谈性能
    还是优化业务逻辑更实在
    akira
        190
    akira  
       2015-12-30 18:43:37 +08:00
    支持阅读性更好的
    jarlyyn
        191
    jarlyyn  
       2015-12-30 18:56:15 +08:00
    @minggeJS

    呵呵

    什么奇葩逻辑

    出错了不弹错,居然还有返回值?

    错误不交给调用者?
    leizongmin
        192
    leizongmin  
       2015-12-30 21:06:26 +08:00
    作为明哥**唯一指定的经纪人**老雷,我要说两句:那个群都是一群善良的人,即使言语过激也不至于人生攻击。还有,**明哥还是一个孩子,大家不要太计较**。
    minggeJS
        193
    minggeJS  
    OP
       2015-12-30 21:40:25 +08:00
    @leizongmin 任何事情你都要给我一个说法,你不给我说法,我给你说法 ----------选自:杨佳杀 JC 被判死刑前名言
    minggeJS
        194
    minggeJS  
    OP
       2015-12-30 21:44:53 +08:00
    @leizongmin 有些委屈如果要一辈子背在身上,那我宁愿犯法。任何事情,你要给我一个说法,你不给我一个说法,我就给你一个说法。。 ----杨 佳


    杨佳的完整语录是这样
    leizongmin
        195
    leizongmin  
       2015-12-30 22:00:02 +08:00
    @minggeJS 群里人人都有那个聊天记录的,仔细看一看,所有人与你讨论时的言语都是比较正常的,并没有任何明显的攻击性行为。反倒是你,自尊心太强了。
    minggeJS
        196
    minggeJS  
    OP
       2015-12-30 22:36:10 +08:00
    @jarlyyn 那你来写了!应该怎么样, 每段程序有他不同的情况, 肯定要看当时的情况而定!那你来写吧,写一段给我看
    zhfish
        197
    zhfish  
       2015-12-30 22:39:18 +08:00
    http://jsperf.com/try-for-cost 很不错。。。能少用就少用咯。
    freaks
        198
    freaks  
       2015-12-30 22:44:39 +08:00
    准备翻页了,倒计时,3~2~1~duang
    jarlyyn
        199
    jarlyyn  
       2015-12-30 23:41:52 +08:00
    @minggeJS

    按照你的风格,代码应该是这样。虽然依然有问题。

    function test(foo) {
    try{
    var obj = new foo();
    obj.wo.ok.arr.push("帅哥");
    return obj;
    }catch (e){
    if (e.name=='TypeError' || e.name=='ReferenceError'){
    return false;
    }
    throw e;
    }
    }
    PublicID
        200
    PublicID  
       2015-12-30 23:43:18 +08:00
    1  2  3  
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2873 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 37ms · UTC 09:44 · PVG 17:44 · LAX 02:44 · JFK 05:44
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.