我正在调试一些JavaScript,无法解释这个||做什么:

function (title, msg) {
  var title = title || 'Error';
  var msg   = msg || 'Error on Request';
}

为什么这个家伙使用var title = title || 'ERROR'?我有时也看到它没有var声明。


当前回答

如果没有设置title,则使用'ERROR'作为默认值。

更通用的:

var foobar = foo || default;

读取:将foobar设置为foo或默认值。 你甚至可以把这个串起来很多次:

var foobar = foo || bar || something || 42;

其他回答

双管代表逻辑上的“或”。这不是真正的情况下,“参数未设置”,因为严格在JavaScript中,如果你有这样的代码:

function foo(par) {
}

然后调用

foo()
foo("")
foo(null)
foo(undefined)
foo(0)

不相等。

双管道(||)将把第一个参数强制转换为布尔值,如果结果布尔值为真-执行赋值,否则它将赋值正确的部分。

如果你检查未设置参数,这很重要。

我们有一个函数setSalary,它有一个可选参数。如果用户没有提供参数,则应该使用默认值10。

如果你这样检查:

function setSalary(dollars) {
    salary = dollars || 10
}

这将为调用提供一个意想不到的结果,例如:

setSalary(0)

它仍然会按照上面描述的流程设置10。

虽然Cletus的回答是正确的,但我觉得应该在JavaScript中添加更多关于“评估为假”的细节。

var title = title || 'Error';
var msg   = msg || 'Error on Request';

不仅仅是检查是否提供了title/msg,而且还检查它们中的任何一个是假的。即下列其中一项:

假的。 0(零) ""(空字符串) null。 未定义的。 NaN(一个特殊的数字值,意思不是一个数字!)

在这一行中

var title = title || 'Error';

如果title为真(即,不是假的,所以title = "titleMessage"等),那么布尔OR(||)运算符已经找到了一个“真”值,这意味着它的计算结果为真,因此它短路并返回真值(title)。

如果title是假的(即上面的列表之一),那么布尔OR(||)运算符已经找到了一个“假”值,现在需要计算运算符的另一部分“Error”,该运算符的计算结果为真,因此返回。

如果运算符两边的值都为false,它也会返回第二个“falsy”运算符(经过一些快速的firebug控制台实验)。

i.e.

return ("" || undefined)

返回undefined,这可能是为了允许您在尝试将title/message默认为""时使用此问题中询问的行为。也就是跑步之后

var foo = undefined
foo = foo || ""

Foo将被设置为""

为了对我前面所说的一切进行解释,我应该给你们一些例子来理解逻辑概念。

var name = false || "Mohsen"; # name equals to Mohsen
var family = true || "Alizadeh" # family equals to true

这意味着如果左边的语句被赋值为true,那么它将被结束,左边的语句将被返回并赋值给变量。在其他情况下,右侧将返回并分配。

和运算符有相反的结构,如下所示。

var name = false && "Mohsen" # name equals to false
var family = true && "Alizadeh" # family equals to Alizadeh

基本上,它检查||之前的值是否为true。如果是,则取该值,如果不是,则取||之后的值。

它将取||之后的值(据我所知):

未定义的 假 0 (Null或空字符串)

我还要补充一点:这种简写令人厌恶。它误用了一个意外的解释器优化(如果第一个操作为真,就不麻烦第二个操作)来控制赋值。这种用法与操作符的目的无关。我不认为它应该被使用。

我更喜欢用三元运算符来初始化,例如,

var title = title?title:'Error';

这使用一行条件操作来达到正确的目的。它仍然与真实玩难看的游戏,但这是JavaScript为你。