我正在调试一些JavaScript,无法解释这个||
的作用?
function (title, msg) {
var title = title || 'Error';
var msg = msg || 'Error on Request';
}
有人可以给我一个提示,为什么这个人正在使用var title = title || 'ERROR'
?我有时也会在没有var
声明的情况下看到它。
答案 0 :(得分:183)
这意味着title
参数是可选的。因此,如果您调用没有参数的方法,它将使用默认值"Error"
。
这是写作的简写:
if (!title) {
title = "Error";
}
这种带有布尔表达式的速记技巧在Perl中也很常见。用表达式:
a OR b
如果true
或a
为b
,则评估为true
。因此,如果a
为真,则根本不需要检查b
。这称为短路布尔评估,所以:
var title = title || "Error";
基本上检查title
是否评估为false
。如果是,则“返回”"Error"
,否则返回title
。
答案 1 :(得分:158)
||
)?双管道运算符(||
)是逻辑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会将隐式会话设置为布尔值。这意味着如果值为false(例如0
,""
,null
,undefined
(另请参阅All falsey values in JavaScript)),则会将其视为{ {1}};否则它被视为false
。
所以上面的例子应该给出true
,因为空函数是真的。嗯,它没有。它返回空函数。这是因为JavaScript的true
运算符不像我在开头写的那样工作。它的工作方式如下:
惊讶?实际上,它是"兼容"使用传统的||
运算符。它可以写成以下函数:
||
如果您将真实值传递为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."
;否则你得到y
。
现在,当您知道"Neither x nor y is truthy"
运算符的工作原理时,您可以自己了解||
的含义。如果x = x || y
是真实的,x
被分配给x
,那么实际上没有任何反应;否则x
被分配给y
。它通常用于定义函数中的默认参数。但是,它通常被认为是糟糕的编程习惯,因为它会阻止您将falsey值(不一定是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
虽然时间更长,但它始终有效并且更容易理解。
您也可以使用the ES6 syntax for default function parameters,但请注意,它不适用于较旧的浏览器(如IE)。如果您想支持这些浏览器,则应使用Babel来转换代码。
答案 2 :(得分:28)
如果未设置title,请使用“ERROR”作为默认值。
更通用:
var foobar = foo || default;
读取:将foobar设置为foo
或default
。
你甚至可以把它连锁多次:
var foobar = foo || bar || something || 42;
答案 3 :(得分:14)
稍微解释一下......
||
运算符是逻辑 - or
运算符。如果第一部分为真,则结果为true;如果第二部分为真,则结果为true;如果两部分均为真,则结果为true。为清楚起见,这里有一个表格:
X | Y | X || Y
---+---+--------
F | F | F
---+---+--------
F | T | T
---+---+--------
T | F | T
---+---+--------
T | T | T
---+---+--------
现在注意到了什么?如果X
为真,则结果始终为true。因此,如果我们知道X
是真的,我们根本不需要检查Y
。因此,许多语言为逻辑 - or
(以及来自另一个方向的逻辑 - and
)实现“短路”评估器。他们检查第一个元素,如果这是真的,他们根本不打扰检查第二个元素。结果(逻辑上)是相同的,但就执行而言,如果第二个元素的计算成本很高,则可能存在巨大差异。
那么这与你的例子有什么关系呢?
var title = title || 'Error';
让我们来看看。 title
元素将传递给您的函数。在JavaScript中,如果未传入参数,则默认为空值。同样在JavaScript中,如果您的变量是空值,则逻辑运算符将其视为false。因此,如果使用给定的标题调用此函数,则它是非假值,因此分配给局部变量。但是,如果没有给出值,则它是空值,因此是假的。然后逻辑 - or
运算符计算第二个表达式并返回'Error'。所以现在局部变量的值为'Error'。
这是因为在JavaScript中实现了逻辑表达式。它不会返回一个正确的布尔值(true
或false
),而是返回它在某些规则下给出的值,该值被认为等同于true
以及被认为等同于{ {1}}。查找您的JavaScript参考,以了解JavaScript在布尔上下文中认为是真或假的。
答案 4 :(得分:7)
基本上它会检查||之前的值计算结果为true,如果是,则采用此值,如果不是,则采用||。
之后的值在||之后取值的值(据我记得):
答案 5 :(得分:7)
双管代表逻辑“OR”。当“参数未设置”时,情况并非如此,因为如果你有这样的代码,严格来说在javascript中:
function foo(par) {
}
然后调用
foo()
foo("")
foo(null)
foo(undefined)
foo(0)
不等同。
Double pipe(||)会将第一个参数转换为boolean,如果得到的boolean为true,则执行赋值,否则将分配正确的部分。
如果您检查未设置的参数,这很重要。
假设我们有一个函数setSalary,它有一个可选参数。如果用户未提供参数,则应使用默认值10。
如果您按照以下方式进行检查:
function setSalary(dollars) {
salary = dollars || 10
}
这会在调用时产生意外结果,如
setSalary(0)
它仍将按照上述流程设置10。
答案 6 :(得分:4)
双管操作员
这个例子有用吗?
var section = document.getElementById('special');
if(!section){
section = document.getElementById('main');
}
也可以
var section = document.getElementById('special') || document.getElementById('main');
答案 7 :(得分:4)
虽然Cletus' answer是正确的,但我觉得应该添加更多关于"评估为false"在JavaScript中。
var title = title || 'Error';
var msg = msg || 'Error on Request';
不仅要检查是否已提供title / msg,还要检查其中任何一个是falsy。即以下之一:
- 假。
- 0(零)
- "" (空字符串)
- 空。
- 未定义。
- NaN(一个特殊的数字值,意思是非数字!)
所以在行
var title = title || 'Error';
如果标题是真实的(即,不是假的,那么title =" titleMessage"等等)那么布尔OR(||)运算符找到了一个真正的' value,表示它的计算结果为true,因此它会短路并返回真值(title)。
如果标题是假的(即上面列表中的一个),那么布尔OR(||)运算符找到了一个' false'值,现在需要评估运算符的其他部分,' Error',其值为true,因此返回。
如果运营商的双方评价为假,它也会(在一些快速的firebug控制台实验之后),它会返回第二个' falsy'操作
即
return ("" || undefined)
返回undefined,这可能允许您在尝试将标题/消息默认为""时使用此问题中询问的行为。即在跑完之后
var foo = undefined
foo = foo || ""
foo将被设置为""
答案 8 :(得分:4)
为了向我前面的所有人说一些解释,我应该给你一些例子来理解逻辑概念。
var name = false || "Mohsen"; # name equals to Mohsen
var family = true || "Alizadeh" # family equals to true
这意味着如果左侧被评估为真实语句,它将被完成并且左侧将被返回并分配给变量。在其他情况下,右侧将被退回并分配。
和运算符具有相反的结构,如下所示。
var name = false && "Mohsen" # name equals to false
var family = true && "Alizadeh" # family equals to Alizadeh
答案 9 :(得分:2)
引用:“构造x = x || y是什么意思?”
指定默认值。
这意味着提供y到x 的默认值, 如果x仍在等待其值但尚未收到它或被故意省略以便回退到默认值。
答案 10 :(得分:0)
|| 是布尔OR运算符。与javascript中一样,将 undefined,null,0,false 视为 fassy 值。
它只是意味着
true || true = true
false || true = true
true || false = true
false || false = false
undefined || "value" = "value"
"value" || undefined = "value"
null || "value" = "value"
"value" || null = "value"
0 || "value" = "value"
"value" || 0 = "value"
false || "value" = "value"
"value" || false = "value"
答案 11 :(得分:-5)
我还要补充一点:这一点速记是令人厌恶的。它错误地使用了意外的解释器优化(如果第一个操作不是第二次操作则不打扰)来控制一个任务。该用途与操作员的目的无关。我不相信它应该被使用。
我更喜欢三元运算符进行初始化,例如
var title = title?title:'Error';
这为正确的目的使用单行条件操作。它仍然会玩真实的难看的游戏,但是,这是你的Javascript。