我正在调试一些 JavaScript 并且无法解释它的||
作用:
function (title, msg) {
var title = title || 'Error';
var msg = msg || 'Error on Request';
}
这家伙为什么用var title = title || 'ERROR'
?我有时也会在没有var
声明的情况下看到它。
我正在调试一些 JavaScript 并且无法解释它的||
作用:
function (title, msg) {
var title = title || 'Error';
var msg = msg || 'Error on Request';
}
这家伙为什么用var title = title || 'ERROR'
?我有时也会在没有var
声明的情况下看到它。
这意味着title
参数是可选的。因此,如果您不带参数调用该方法,它将使用默认值"Error"
.
这是写作的简写:
if (!title) {
title = "Error";
}
这种布尔表达式的速记技巧在 Perl 中也很常见。用表达式:
a OR b
它评估为true
ifa
或b
is true
。所以如果a
是真的,你根本不需要检查b
。这称为短路布尔评估,因此:
var title = title || "Error";
基本上检查是否title
评估为false
. 如果是,则“返回” "Error"
,否则返回title
。
||
)?双管道运算符 ( ||
) 是逻辑OR
运算符。在大多数语言中,它的工作方式如下:
false
,它会检查第二个值。如果是true
,则返回true
,如果第二个值为false
,则返回false
。true
,它总是返回true
,无论第二个值是什么。所以基本上它的工作原理是这样的:
function or(x, y) {
if (x) {
return true;
} else if (y) {
return true;
} else {
return false;
}
}
如果还是不明白,请看这张表:
| true false
------+---------------
true | true true
false | true false
换句话说,只有当两个值都为假时才为假。
JavaScript 有点不同,因为它是一种松散类型的语言。在这种情况下,这意味着您可以使用||
带有非布尔值的运算符。虽然没有意义,但您可以将此运算符用于例如函数和对象:
(function(){}) || {}
如果值不是布尔值,JavaScript 会隐式转换为 boolean。这意味着如果值是假的(例如0
, ""
, null
, undefined
(另请参阅JavaScript 中的所有假值)),它将被视为false
; 否则它被视为true
.
所以上面的例子应该给出true
,因为空函数是真的。好吧,它没有。它返回空函数。那是因为 JavaScript 的||
操作符不像我一开始写的那样工作。它的工作方式如下:
惊讶?实际上,它与传统||
运算符“兼容” 。可以写成如下函数:
function or(x, y) {
if (x) {
return x;
} else {
return y;
}
}
如果您将真值作为 传递x
,它会返回x
,即真值。因此,如果您稍后在if
子句中使用它:
(function(x, y) {
var eitherXorY = x || y;
if (eitherXorY) {
console.log("Either x or y is truthy.");
} else {
console.log("Neither x nor y is truthy");
}
}(true/*, undefined*/));
你得到"Either x or y is truthy."
。
如果x
是假的,eitherXorY
将是y
。在这种情况下,您会得到"Either x or y is truthy."
ify
为真;否则你会得到"Neither x nor y is truthy"
.
现在,当您知道||
运算符的工作原理时,您可能会自己弄明白x = x || y
是什么意思。如果x
为真,x
则分配给x
,因此实际上什么也没发生;否则y
分配给x
。它通常用于定义函数中的默认参数。但是,它通常被认为是一种糟糕的编程习惯,因为它会阻止您将错误值(不一定是undefined
或null
)作为参数传递。考虑以下示例:
function badFunction(/* boolean */flagA) {
flagA = flagA || true;
console.log("flagA is set to " + (flagA ? "true" : "false"));
}
乍一看,它看起来很有效。但是,如果您false
作为flagA
参数传递(因为它是布尔值,即可以是true
或false
)会发生什么?它会变成true
. 在这个例子中,没有办法设置flagA
为false
。
明确检查是否flagA
为是一个更好的主意undefined
,如下所示:
function goodFunction(/* boolean */flagA) {
flagA = typeof flagA !== "undefined" ? flagA : true;
console.log("flagA is set to " + (flagA ? "true" : "false"));
}
虽然它更长,但它总是有效并且更容易理解。
您还可以将 ES6 语法用于默认函数参数,但请注意,它不适用于旧浏览器(如 IE)。如果你想支持这些浏览器,你应该使用Babel转译你的代码。
另请参阅MDN 上的逻辑运算符。
如果未设置标题,则使用“错误”作为默认值。
更通用:
var foobar = foo || default;
读取:将 foobar 设置为foo
或default
。你甚至可以多次链接它:
var foobar = foo || bar || something || 42;
稍微解释一下这个...
该||
操作是logical-or
操作。如果第一部分为真,则结果为真,如果第二部分为真,则结果为真,如果两部分都为真,则结果为真。为了清楚起见,这里有一张表:
X | Y | X || Y
---+---+--------
F | F | F
---+---+--------
F | T | T
---+---+--------
T | F | T
---+---+--------
T | T | T
---+---+--------
现在注意到这里的一些东西了吗?如果X
为真,则结果始终为真。因此,如果我们知道这X
是真的,我们根本不必检查Y
。因此,许多语言为逻辑- or
(和and
来自另一个方向的逻辑-)实现了“短路”评估器。他们检查第一个元素,如果这是真的,他们根本不会检查第二个元素。结果(在逻辑方面)是相同的,但在执行方面,如果第二个元素的计算成本很高,则可能存在巨大差异。
那么这和你的例子有什么关系呢?
var title = title || 'Error';
让我们来看看。该title
元素被传递给您的函数。在 JavaScript 中,如果不传入参数,则默认为空值。同样在 JavaScript 中,如果您的变量是空值,则逻辑运算符将其视为假。因此,如果在给定标题的情况下调用此函数,则它是一个非假值,因此分配给局部变量。然而,如果它没有被赋予一个值,它就是一个空值,因此是假的。然后逻辑or
运算符计算第二个表达式并返回“错误”。所以现在局部变量被赋予值“错误”。
这是因为在 JavaScript 中实现了逻辑表达式。它不返回正确的布尔值(true
或false
),而是返回根据某些规则给出的值,关于什么被认为是等价于true
什么被认为是等价于false
。查找您的 JavaScript 参考以了解 JavaScript 在布尔上下文中认为是对还是错。
基本上,它检查||
评估之前的值是否为真。如果是,则取此值,如果不是,则取||
.
将取值后的值||
(据我所知):