源码在: 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()回调函数
1
zhandi4 2021-07-23 17:44:36 +08:00 1
逻辑是先执行校验方法_validateForm,校验成功后如果有提交方法_onsubmit 就执行。
可以用链判断符号来精简 ```javascript return that._validateForm(evt) && _onsubmit?.() ``` |
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; 好麻烦呀还是原来的好 |
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; } |
4
libook 2021-07-23 18:36:04 +08:00 1
简单理解就是:
&&左边为假值(不只有 false )的话就返回左边的值,且不执行右侧表达式;左边为真值(不只有 true )的话就执行右侧的表达式,并返回右侧的值。这块比较容易出 bug 的情况是如果左侧返回了 0 或者空字符串,那么预期依然要执行右侧的时候,此时依然不会执行右侧。 ||左边为真值(不只有 true )的的话就返回左边的值,且不执行右测表达式;左边为假值的时候(不只有 false )就会执行右侧的表达式,然后返回右侧的值。这块比较容易出 bug 的情况就是左侧返回了 0 或者空字符串,那么预期不执行右侧表达式的时候,此时依然会执行右侧表达式并返回右侧的值。 JS 是一们很灵活的语言,但也因此对写代码的人要求很高。 |
5
zhujinliang 2021-07-23 18:52:01 +08:00 via iPhone 1
其实可以不用管他什么&&和||之类的
三件事,验证表单、判断_onsubmit 是否为空、执行_onsubmit 可以猜测_onsubmit 不为空才可被执行,表单验证通过才会执行_onsubmit 。结合上下文,这里是新构造了一个函数,用来替代表单本身的 onsubmit,为其赋予验证表单功能,符合上面的逻辑 最后注意当表单验证失败时返回的是_validate Form 函数的返回值,验证成功后返回的是_onsubmit 的返回值。表单验证一般会返回验证失败的原因,这个需要返回给调用着以便提示用户 |
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 |
7
manyfreebug OP @no1xsyzy
@zhujinliang 翻看了提交的第一版源码,当时是没有(_onsubmit === undefined || _onsubmit()) 这个步骤的,所以提交的版本中, 大概是基于什么原因考虑才加上这块代码的呢? https://github.com/rickharrison/validate.js/commit/ba3203e7793d3511af6cf75ebf4fcee18d697e28#diff-8f0afd405124af3c1f98ff3df561db0ae1978acd21b3e89682c8795b961fff17R100 |
8
manyfreebug OP 所以提交的版本 -> 后面提交的版本
|
9
no1xsyzy 2021-07-24 16:37:07 +08:00 1
|
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,验证然后提交。 |