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

怎样用 if(或其他更清晰的)语句代替下面这行短路求值(&&和||)的代码?

  •  
  •   manyfreebug · 2021-07-23 17:31:20 +08:00 · 1871 次点击
    这是一个创建于 1219 天前的主题,其中的信息可能已经有所发展或是发生改变。

    源码在: https://github.com/rickharrison/validate.js/blob/master/validate.js#L126

    var _onsubmit = this.form.onsubmit;
    
    this.form.onsubmit = (function(that) {
        return function(evt) {
            try {
                return that._validateForm(evt) && (_onsubmit === undefined || _onsubmit());
            } catch(e) {}
        };
    })(this);
    
    其中这行代码, 作者想表达的意思是什么?
    return that._validateForm(evt) && (_onsubmit === undefined || _onsubmit())
    

    怎样用 if(或其他更清晰的)语句代替下面这行短路求值(&&和||)的代码?:

    return that._validateForm(evt) && (_onsubmit === undefined || _onsubmit());
    
    that._validateForm(evt) 上半段代码似乎总是会执行
    
    (_onsubmit === undefined || _onsubmit())
    等价于:
    if(_onsubmit) {
        _onsubmit();
    }
    这半段代码, 作者想表达的意思似乎是: 如果在 form 元素上添加了 onsubmit 事件属性,则执行_onsubmit()回调函数
    
    
    10 条回复    2021-07-25 13:37:40 +08:00
    zhandi4
        1
    zhandi4  
       2021-07-23 17:44:36 +08:00   ❤️ 1
    逻辑是先执行校验方法_validateForm,校验成功后如果有提交方法_onsubmit 就执行。
    可以用链判断符号来精简
    ```javascript
    return that._validateForm(evt) && _onsubmit?.()
    ```
    IvanLi127
        2
    IvanLi127  
       2021-07-23 17:50:26 +08:00   ❤️ 1
    我觉得这代码。。挺清晰的。。。如果 _validateForm 成功,那么尝试 _onsubmit
    改写的话就是:
    const validateResult = that._validateForm(evt);
    if (validateResult) return _onsubmit?.();
    else return validateResult;

    好麻烦呀还是原来的好
    libook
        3
    libook  
       2021-07-23 18:28:18 +08:00   ❤️ 1
    这种用法其实是就是利用了逻辑与和逻辑或的执行和不执行的特性,以及 JS 的返回值的机制来简化了 if/else 的写法,个人认为算是取巧的方式,也在各种代码里极其常见,但个人不喜欢,这个不是很清晰的逻辑,需要大脑模拟执行过程来转化成条件关系的,在不熟练或比较疲劳的时候会加大读错或写错的几率。

    const isValid = that._validateForm(evt); // 假设返回 Boolean 类型
    if (isValid) {
    if (_onsubmit === undefined) {
    return false
    } else {
    return _onsubmit();
    }
    } else {
    return false;
    }
    libook
        4
    libook  
       2021-07-23 18:36:04 +08:00   ❤️ 1
    简单理解就是:
    &&左边为假值(不只有 false )的话就返回左边的值,且不执行右侧表达式;左边为真值(不只有 true )的话就执行右侧的表达式,并返回右侧的值。这块比较容易出 bug 的情况是如果左侧返回了 0 或者空字符串,那么预期依然要执行右侧的时候,此时依然不会执行右侧。
    ||左边为真值(不只有 true )的的话就返回左边的值,且不执行右测表达式;左边为假值的时候(不只有 false )就会执行右侧的表达式,然后返回右侧的值。这块比较容易出 bug 的情况就是左侧返回了 0 或者空字符串,那么预期不执行右侧表达式的时候,此时依然会执行右侧表达式并返回右侧的值。

    JS 是一们很灵活的语言,但也因此对写代码的人要求很高。
    zhujinliang
        5
    zhujinliang  
       2021-07-23 18:52:01 +08:00 via iPhone   ❤️ 1
    其实可以不用管他什么&&和||之类的
    三件事,验证表单、判断_onsubmit 是否为空、执行_onsubmit
    可以猜测_onsubmit 不为空才可被执行,表单验证通过才会执行_onsubmit 。结合上下文,这里是新构造了一个函数,用来替代表单本身的 onsubmit,为其赋予验证表单功能,符合上面的逻辑
    最后注意当表单验证失败时返回的是_validate Form 函数的返回值,验证成功后返回的是_onsubmit 的返回值。表单验证一般会返回验证失败的原因,这个需要返回给调用着以便提示用户
    no1xsyzy
        6
    no1xsyzy  
       2021-07-23 20:00:10 +08:00   ❤️ 1
    看了下 _validateForm 的源码,最清晰的等价是

    that._validateForm(evt);
    return _onsubmit();

    为什么不需要存储 validateResult ? 因为 _validateForm 只会返回 true 或者抛异常(连 false 和 undefined 都不可能,抛异常还是因为「所有 JavaScript 代码都可能抛异常」这个问题,而不是它本身想抛异常)
    为什么不需要检查 onsubmit ?因为直接 () 会抛异常就是了
    两种情况都会被 catch
    manyfreebug
        7
    manyfreebug  
    OP
       2021-07-24 15:13:50 +08:00
    @no1xsyzy
    @zhujinliang
    翻看了提交的第一版源码,当时是没有(_onsubmit === undefined || _onsubmit()) 这个步骤的,所以提交的版本中, 大概是基于什么原因考虑才加上这块代码的呢?

    https://github.com/rickharrison/validate.js/commit/ba3203e7793d3511af6cf75ebf4fcee18d697e28#diff-8f0afd405124af3c1f98ff3df561db0ae1978acd21b3e89682c8795b961fff17R100
    manyfreebug
        8
    manyfreebug  
    OP
       2021-07-24 15:15:00 +08:00
    所以提交的版本 -> 后面提交的版本
    msg7086
        10
    msg7086  
       2021-07-25 13:37:40 +08:00   ❤️ 1
    另外,and 和 or 本来可以按照英语语法去理解。

    比如 mysql_connect || exit,用英语来读就是,connect to MySQL or exit,连上数据库,要不然就退出。
    比如 validate && submit,用英语来读就是,validate and submit,验证然后提交。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2016 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 00:54 · PVG 08:54 · LAX 16:54 · JFK 19:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.