javascript - 这两段js的写法是否完全等价?
ringa_lee
ringa_lee 2017-04-10 12:48:14
[JavaScript讨论组]

前者:

greeting = "hello" + (username ? username : "friend")  

后者:

greeting = "hello" + (username || "friend")

下面有个回答明显对js的逻辑或操作符没有理解到位,我简单解释一下 username || "friend" 其中 username 是个标识符,可能这个变量已经定义,也可能没有定义。

逻辑或操作符的操作数可以为任意类型,并且不一定总是返回 boolean 类型,且两个操作数的值不一定全部被计算,如果左操作数为真,则直接返回左操作数的值,注意,不是返回 true,而是左操作数的值,也就是说 4 || 0 返回的是 4,而不是 true,这种情况下右操作数将直接被忽略。如果左操作数为假,则直接返回右操作数的值,例如 0 || "hello world" 将会返回 "hello world"

ringa_lee
ringa_lee

ringa_lee

全部回复(7)
天蓬老师

ecmascript 规范

二元逻辑运算符 http://ecmascript.cn/#208

产生式 LogicalORExpression : LogicalORExpression || LogicalANDExpression 按照下面的过程执行 :

  1. 令 lref 为解释执行 LogicalORExpression 的结果 .
  2. 令 lval 为 GetValue(lref).
  3. 如果 ToBoolean(lval) 为 true ,返回 lval.
  4. 令 rref 为解释执行 LogicalANDExpression 的结果 .
  5. 返回 GetValue(rref).

LogicalANDExpressionNoInLogicalORExpressionNoIn 执行完全按照 LogicalANDExpressionLogicalORExpression 相同的方式,BitwiseORExpressionNoInLogicalORExpressionNoIn 替代了 BitwiseORExpressionLogicalORExpression 除外。

注:由 && 或者 || 运算符产生的值不是必须为Boolean类型,产生的值始终为两个运算表达式的结果之一。

条件运算符 http://ecmascript.cn/#209

产生式 ConditionalExpression : LogicalORExpression ? AssignmentExpression : AssignmentExpression 按照下面的过程执行 :

  1. 令 lref 为解释执行 LogicalORExpression 的结果 .
  2. 如果 ToBoolean(GetValue(lref)) 为 true ,那么: 令 trueRef 为解释执行第一个 AssignmentExpression 的结果 . 返回 GetValue(trueRef).
  3. Else 令 falseRef 为解释执行第二个 AssignmentExpression 的结果 . 返回 GetValue(falseRef).

ConditionalExpressionNoIn 执行完全按照 ConditionalExpression 相同的方式,除了AssignmentExpressionAssignmentExpressionNoIn 替代了第一个 AssignmentExpression 和第二个 AssignmentExpression

注:ECMAScript中的ConditionalExpression跟C和Java有一点点不同,它允许第二个子表达式是个Expression但是限制第三个表达式必须是ConditionalExpression。ECMAScript中这个差别的依据是可以允许允许赋值表达式出现在条件的任意一侧同时避免逗号表达式作为中间的表达式时无用且易混淆的使用方式。


这两种表达方式完全等价。

巴扎黑

可以从编译器性能优化的角度来看。

在诸如C、C++、java的语言里面,形如 a || b 的结构,a做真值判断结果为 true 的时候,没有必要做b的真值判断,因为根据操作符“或”的定义,只要二者有一个为真即可。因此在a真值判断结果为 true 的时候,编译器不需要计算b的值,按相应语言标准,返回a或者true。

在javascript这个语言里,“或”操作符并不一定返回boolean类型的值。上面的编译优化方式依然成立的,对于形如 a || b 的结构,编译器有以下的步骤:

  • 首先判断a的真值,看其是否为“falsy”(“falsy”,即一个值为false0""(即空字符串),nullundefinedNaN之一的时候)
  • 在a为非“falsy”的时候,不计算b,直接返回a(编译优化)
  • 在a为“falsy”的时候,由于js的或表达式不需要返回boolean类型的值,略去b的真值判断。又因为b的值直接反映了 false || b 表达式的值,直接返回b

正因此,这两段js的写法完全等价。

更多类似的js写法,还有:

window.console && window.console.log("hello world") ;

等同于

if ( window.console ) {
    window.console.log("hello world") ;
}
天蓬老师

功能上一致

如果要实现同样的功能,后者更精炼.一般都会这么写.

前面那种使用场景一般是:

greeting = "hello" + (user ? user.name : "friend")  
天蓬老师
username=''
//输出: ""
username || "friend"
//输出: "friend"
username ? username : "friend"
//输出: "friend"

你可以用浏览器自带的debugger查看一下,应该是一样的

高洛峰

不一样!!!!!

高洛峰

等价的。上面那种写法其实也就是逻辑或运算。

天蓬老师

等价的 ,只是两种不同的写法

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号