JavaScript OR (||) 变量赋值说明
鉴于这段 JavaScript 代码...
var a;
var b = null;
var c = undefined;
var d = 4;
var e = 'five';
var f = a || b || c || d || e;
alert(f); // 4
有人可以向我解释一下这种技术的名称吗(我最好的猜测是在这个问题的标题中!)?以及它到底是如何/为什么起作用的?
我的理解是,变量 f
将被分配第一个变量的最接近的值(从左到右),该变量的值既不是 null 也不是未定义的,但我还没有找到关于该技术的参考资料很多,并且已经被广泛使用。
另外,这种技术是 JavaScript 特有的吗?我知道在 PHP 中做类似的事情会导致 f
具有真正的布尔值,而不是 d
本身的值。
Given this snippet of JavaScript...
var a;
var b = null;
var c = undefined;
var d = 4;
var e = 'five';
var f = a || b || c || d || e;
alert(f); // 4
Can someone please explain to me what this technique is called (my best guess is in the title of this question!)? And how/why it works exactly?
My understanding is that variable f
will be assigned the nearest value (from left to right) of the first variable that has a value that isn't either null or undefined, but I've not managed to find much reference material about this technique and have seen it used a lot.
Also, is this technique specific to JavaScript? I know doing something similar in PHP would result in f
having a true boolean value, rather than the value of d
itself.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
返回输出第一个真实值。
如果全部为 false,则返回最后一个 false 值。
例子:-
Return output first true value.
If all are false return last false value.
Example:-
其称为短路运算符。
短路求值表示,仅当第一个参数不足以确定表达式的值时才执行或求值第二个参数。当 OR (||) 函数的第一个参数计算结果为 true 时,整体值必须为 true。
它还可以用于设置函数参数的默认值。
Its called Short circuit operator.
Short-circuit evaluation says, the second argument is executed or evaluated only if the first argument does not suffice to determine the value of the expression. when the first argument of the OR (||) function evaluates to true, the overall value must be true.
It could also be used to set a default value for function argument.`
它将新变量 (
z
) 设置为x
的值(如果它是“true”)(非零,有效的对象/数组/函数/无论它是什么)或y
否则。这是在x
不存在的情况下提供默认值的一种相对常见的方法。例如,如果您有一个带有可选回调参数的函数,您可以提供一个不执行任何操作的默认回调:
It's setting the new variable (
z
) to either the value ofx
if it's "truthy" (non-zero, a valid object/array/function/whatever it is) ory
otherwise. It's a relatively common way of providing a default value in casex
doesn't exist.For example, if you have a function that takes an optional callback parameter, you could provide a default callback that doesn't do anything:
这意味着如果设置了
x
,则z
的值将为x
,否则如果设置了y
则它的值将被设置为z
的值。它与
It's possiblebecause JavaScript 中的逻辑运算符不返回布尔值,而是返回完成操作所需的最后一个元素的值(在 OR 语句中,它将是第一个非 false 值,在 AND 语句中,它会成为最后一个)。如果操作失败,则返回
false
。It means that if
x
is set, the value forz
will bex
, otherwise ify
is set then its value will be set as thez
's value.it's the same as
It's possible because logical operators in JavaScript doesn't return boolean values but the value of the last element needed to complete the operation (in an OR sentence it would be the first non-false value, in an AND sentence it would be the last one). If the operation fails, then
false
is returned.它将计算 X,如果 X 不为 null、空字符串或 0(逻辑假),则将其分配给 z。如果 X 为 null、空字符串或 0(逻辑假),则它将把 y 分配给 z。
将输出'bob';
It will evaluate X and, if X is not null, the empty string, or 0 (logical false), then it will assign it to z. If X is null, the empty string, or 0 (logical false), then it will assign y to z.
Will output 'bob';
根据比尔·希金斯的博客帖子; Javascript 逻辑或赋值惯用法 (2007 年 2 月),这种行为从 v1.2 开始是正确的(至少)
他还建议了它的另一种用途(引用):
“跨浏览器差异的轻量级标准化”
According to the Bill Higgins' Blog post; the Javascript logical OR assignment idiom (Feb. 2007), this behavior is true as of v1.2 (at least)
He also suggests another use for it (quoted):
"lightweight normalization of cross-browser differences"
有关说明,请参阅短路评估。这是实现这些运算符的常见方法;它并不是 JavaScript 所独有的。
See short-circuit evaluation for the explanation. It's a common way of implementing these operators; it is not unique to JavaScript.
这是为了分配一个默认值,在本例中是
y
的值,如果x
变量是falsy >。JavaScript 中的布尔运算符可以返回操作数,但并不总是像其他语言中那样返回布尔结果。
如果第一个操作数为假,则逻辑 OR 运算符 (
||
) 返回第二个操作数的值,否则返回第一个操作数的值。例如:
Falsy 值是指在布尔上下文中使用时强制为
false
的值,它们是0
、null
>、未定义
、空字符串、NaN
,当然还有false
。This is made to assign a default value, in this case the value of
y
, if thex
variable is falsy.The boolean operators in JavaScript can return an operand, and not always a boolean result as in other languages.
The Logical OR operator (
||
) returns the value of its second operand, if the first one is falsy, otherwise the value of the first operand is returned.For example:
Falsy values are those who coerce to
false
when used in boolean context, and they are0
,null
,undefined
, an empty string,NaN
and of coursefalse
.Javacript 对逻辑运算符
||
使用 短路求值 和<代码>&&。 但是,它与其他语言的不同之处在于,它返回停止执行的最后一个值的结果,而不是true
或false
值。以下值在 JavaScript 中被视为 false。
""
(空字符串)忽略 运算符优先级规则,为了简单起见,以下示例显示了哪个值停止了计算,并作为结果返回。
NaN
之前的前 5 个值都是假值,因此它们都是从左到右计算的,直到满足第一个真值 -"Hello"
,这使得整个表达式为 true,因此,任何进一步的内容都不会被计算,并且"Hello"
作为表达式的结果返回。同样,在这种情况下:前 5 个值都是真值,并进行求值,直到满足第一个假值 (
null
),这使得表达式为假,因此2010
是' t 不再计算,并且null
作为表达式的结果返回。您给出的示例是利用 JavaScript 的此属性来执行分配。它可以用在任何需要获取一组值中第一个真值或假值的地方。下面的代码会将值
"Hello"
分配给b
,因为这样可以更轻松地分配默认值,而不是进行 if-else 检查。您可以将下面的示例称为对此功能的利用,我相信它使代码更难以阅读。
在警报中,我们检查
messages
是否为假,如果是,则评估并返回noNewMessagesText
,否则评估并返回newMessagesText
。由于此示例中的内容为假,因此我们在 noNewMessagesText 处停止并警告“抱歉,您没有新消息。”
。Javacript uses short-circuit evaluation for logical operators
||
and&&
. However, it's different to other languages in that it returns the result of the last value that halted the execution, instead of atrue
, orfalse
value.The following values are considered falsy in JavaScript.
""
(empty string)Ignoring the operator precedence rules, and keeping things simple, the following examples show which value halted the evaluation, and gets returned as a result.
The first 5 values upto
NaN
are falsy so they are all evaluated from left to right, until it meets the first truthy value -"Hello"
which makes the entire expression true, so anything further up will not be evaluated, and"Hello"
gets returned as a result of the expression. Similarly, in this case:The first 5 values are all truthy and get evaluated until it meets the first falsy value (
null
) which makes the expression false, so2010
isn't evaluated anymore, andnull
gets returned as a result of the expression.The example you've given is making use of this property of JavaScript to perform an assignment. It can be used anywhere where you need to get the first truthy or falsy value among a set of values. This code below will assign the value
"Hello"
tob
as it makes it easier to assign a default value, instead of doing if-else checks.You could call the below example an exploitation of this feature, and I believe it makes code harder to read.
Inside the alert, we check if
messages
is falsy, and if yes, then evaluate and returnnoNewMessagesText
, otherwise evaluate and returnnewMessagesText
. Since it's falsy in this example, we halt at noNewMessagesText and alert"Sorry, you have no new messages."
.Javascript 变量没有类型,因此可以为 f 分配一个整数值,即使它是通过布尔运算符分配的。
f 被分配为不等于 false 的最接近值。所以0、false、null、undefined都被忽略了:
Javascript variables are not typed, so f can be assigned an integer value even though it's been assigned through boolean operators.
f is assigned the nearest value that is not equivalent to false. So 0, false, null, undefined, are all passed over:
它没有任何魔力。布尔表达式,例如
a ||乙|| c || d
被延迟评估。 Interpeter 查找a
的值,它是未定义的,所以它是 false,所以它继续前进,然后它看到b
是 null,它仍然给出错误的结果,所以它继续前进,然后它看到c
- 同样的故事。最后它看到d
并说“嗯,它不为空,所以我得到了结果”,并将其分配给最终变量。这个技巧适用于所有对布尔表达式进行惰性短路求值的动态语言。在静态语言中,它不会编译(类型错误)。在急于评估布尔表达式的语言中,它将返回逻辑值(即本例中为 true)。
There isn't any magic to it. Boolean expressions like
a || b || c || d
are lazily evaluated. Interpeter looks for the value ofa
, it's undefined so it's false so it moves on, then it seesb
which is null, which still gives false result so it moves on, then it seesc
- same story. Finally it seesd
and says 'huh, it's not null, so I have my result' and it assigns it to the final variable.This trick will work in all dynamic languages that do lazy short-circuit evaluation of boolean expressions. In static languages it won't compile (type error). In languages that are eager in evaluating boolean expressions, it'll return logical value (i.e. true in this case).
这个问题已经得到了几个很好的答案。
总之,该技术利用了语言编译方式的一个特性。也就是说,JavaScript“短路”了布尔运算符的计算,并将返回与第一个非 false 变量值或最后一个变量包含的任何内容关联的值。请参阅 Anurag 对那些计算结果为 false 的值的解释。
由于多种原因,使用这种技术并不是一个好的做法;然而。
代码可读性:这是使用布尔运算符,如果不理解其编译行为,则预期结果将是布尔值。
稳定性:这是使用语言编译方式的一个功能,该功能在多种语言之间是不一致的,因此它可能是未来更改的目标。
记录的功能:有一个现有的替代方案可以满足此需求并且在更多语言中保持一致。这将是三元运算符:
() ?值 1:值 2。
使用三元运算符确实需要更多的输入,但它清楚地区分了正在计算的布尔表达式和正在分配的值。此外,它可以被链接,因此可以重新创建上面执行的默认分配类型。
This question has already received several good answers.
In summary, this technique is taking advantage of a feature of how the language is compiled. That is, JavaScript "short-circuits" the evaluation of Boolean operators and will return the value associated with either the first non-false variable value or whatever the last variable contains. See Anurag's explanation of those values that will evaluate to false.
Using this technique is not good practice for several reasons; however.
Code Readability: This is using Boolean operators, and if the behavior of how this compiles is not understood, then the expected result would be a Boolean value.
Stability: This is using a feature of how the language is compiled that is inconsistent across multiple languages, and due to this it is something that could potentially be targeted for change in the future.
Documented Features: There is an existing alternative that meets this need and is consistent across more languages. This would be the ternary operator:
() ? value 1: Value 2.
Using the ternary operator does require a little more typing, but it clearly distinguishes between the Boolean expression being evaluated and the value being assigned. In addition it can be chained, so the types of default assignments being performed above could be recreated.