本文通过具体代码示例,深入解析JavaScript中连续&&和||运算符的赋值行为。文章指出,&&表达式在遇到0、false、undefined、null或空字符串时返回该值,否则返回最后一个子表达式;||表达式则返回第一个真值子表达式,若全为假则返回最后一个。同时强调了字符串与对应原始类型的布尔转换差异,如'0'为真而0为假。
JavaScript中&&与||运算符的短路赋值行为详解
相关代码实现如下:
具体代码片段如下:
function write(msg){
for(var i = 0; i < arguments.length; i ++){
document.write(arguments[i] + '<br />');
}
}
//关于 '&&'运算符的测试
test1 = 1 && 2 && 3 && 4;
test2 = '0' && 2 && 3 && 4;
test3 = 1 && 2 && 0 && 4;
test4 = 2 && 'i' && 'love' && 3 && 'you';
test5 = 'i' && 'hate' && 1 && 0 && 'you';
test6 = 1 && false && 'ihateyou' && '2';
test7 = 2 && true && 'ihatehateyou' && '23';
test8 = 4 && true && 'undefined' && 'true' && '1';
test9 = 4 && true && undefined && 'true' && '1';
test10 = 4 && true && 'null' && 'true' && '1';
test11 = 4 && true && null && 'true' && '1';
write(test1, test2, test3, test4, test5, test6, test7, test8, test9, test10, test11);
write('----------------------------------------------');
//关于 '||'运算符的测试
_test1 = 1 || 2 || 3 || 4;
_test2 = 0 || 2 || 3 || 4;
_test3 = 0 || '0' || 8 || 4;
_test4 = 2 || 'i' || 'love' || 0 || 'you';
_test5 = 0 || 'hate' || 1 || 0 || 'you';
_test6 = false || 0 || 'ihateyou' || '2';
_test7 = false || true || 'ihatehateyou' || '23';
_test8 = 0 || 0 || 'undefined' || 'true' || '1';
_test9 = 0 || 0|| undefined || 'true' || '1';
_test10 = 0 || false || 'null' || 'true' || '1';
_test11 = 0 || 0 || null || 'true' || '1';
write(_test1, _test2, _test3, _test4, _test5, _test6, _test7, _test8, _test9, _test10, _test11); 观察以下输出结果即可理解其机制:
关于 ‘&&'的输出结果为:
具体输出代码如下:
4
4
0
you
0
false
23
1
undefined
1
null 每一行的编号对应上面的每一个 test。
关于 ‘||'的输出结果为:
具体输出代码如下:
1
2
0
2
hate
ihateyou
true
undefined
true
null
true 仔细对照分析即可明确其规律:
在多个连续的 && 表达式中,若不存在 0, false, undefined, null 等假值,则返回最后一个“子表达式”的值;若存在假值,则返回第一个遇到的 0, false, undefined, null 值。
多个连续的 || 表达式会返回第一个“子表达式”的值;若该值为 0, false, undefined, null 之一,则继续判断下一个“子表达式”,依此类推,直到找到非假值的“子表达式”并返回它;若所有子表达式均为假值,则返回最后一个子表达式的值。
补充说明:
上述规则似乎未涵盖子表达式为空字符串 '' 的情况。实际上,可以通过另一种表述方式来更准确地描述 && 和 || 的工作机制:
对于 (...) && (...) && (...) ...
从左至右遍历各个子表达式,并对每个子表达式进行 Boolean 强制转换。若出现 Boolean(子表达式) 为 false 的情况,则整个表达式的值即为此子表达式的值(可能是 0、false、undefined、null 或 ''),后续子表达式不再参与判断;若所有 Boolean(子表达式) 均为 true,则整个表达式的值即为最后一个子表达式的值。
对于 (...) || (...) || (...) ...
从左至右遍历各个子表达式,并对每个子表达式进行 Boolean 强制转换。若出现 Boolean(子表达式) 为 true 的情况,则整个表达式的值即为此子表达式的值,后续子表达式不再被“理会”;若 Boolean(子表达式) 为 false,则判断后一个子表达式的 Boolean 情况,直至找到 Boolean(子表达式) 为 true 的情况;若全部 Boolean(子表达式) 均为 false,则返回最后一个子表达式的值(可能是 0、false、undefined、null 或 '')。
这里需要特别注意:
Boolean(false) 不等于 Boolean('false'),前者结果为 false,而后者结果为 true 。
Boolean(undefined) 不等于 Boolean('undefined'),前者结果为 false,而后者结果为 true 。
Boolean(null) 不等于 Boolean('null'),前者结果为 false,而后者结果为 true 。
Boolean(0) 不等于 Boolean('0'),前者结果为 false,而后者结果为 true 。
Boolean('') 等于 false