Javascript 什么是构造 x = x || 你是什​​么意思?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2802055/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 01:59:43  来源:igfitidea点击:

What does the construct x = x || y mean?

javascriptparametersoptional-parametersor-operator

提问by opHASnoNAME

I am debugging some JavaScript, and can't explain what this ||does?

我正在调试一些 JavaScript,但无法解释它的||作用?

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

Can someone give me an hint, why this guy is using var title = title || 'ERROR'? I sometimes see it without a vardeclaration as well.

有人可以给我一个提示,为什么这个人在使用var title = title || 'ERROR'?我有时也会在没有var声明的情况下看到它。

采纳答案by cletus

It means the titleargument is optional. So if you call the method with no arguments it will use a default value of "Error".

这意味着title参数是可选的。因此,如果您不带参数调用该方法,它将使用默认值"Error".

It's shorthand for writing:

这是写作的简写:

if (!title) {
  title = "Error";
}

This kind of shorthand trick with boolean expressions is common in Perl too. With the expression:

这种布尔表达式的速记技巧在 Perl 中也很常见。用表达式:

a OR b

it evaluates to trueif either aor bis true. So if ais true you don't need to check bat all. This is called short-circuit boolean evaluation so:

它评估为trueifabis true。所以如果a是真的,你根本不需要检查b。这称为短路布尔评估,因此:

var title = title || "Error";

basically checks if titleevaluates to false. If it does, it "returns" "Error", otherwise it returns title.

基本上检查是否title评估为false. 如果是,则“返回” "Error",否则返回title

回答by Micha? Per?akowski

What is the double pipe operator (||)?

什么是双管道运算符 ( ||)?

The double pipe operator (||) is the logical ORoperator. In most languagesit works the following way:

双管道运算符 ( ||) 是逻辑OR运算符。在大多数语言中,它的工作方式如下:

  • If the first value is false, it checks the second value. If it's true, it returns trueand if it's false, it returns false.
  • If the first value is true, it always returns true, no matter what the second value is.
  • 如果第一个值是false,它会检查第二个值。如果是true,则返回true,如果是false,则返回false
  • 如果第一个值是true,它总是返回true,无论第二个值是什么。

So basically it works like this function:

所以基本上它的工作原理是这样的:

function or(x, y) {
  if (x) {
    return true;
  } else if (y) {
    return true;
  } else {
    return false;
  }
}

If you still don't understand, look at this table:

如果还是不明白,请看这张表:

      | true   false  
------+---------------
true  | true   true   
false | true   false  

In other words, it's only false when both values are false.

换句话说,只有当两个值都为假时才为假。

How is it different in JavaScript?

它在 JavaScript 中有什么不同?

JavaScript is a bit different, because it's a loosely typed language. In this case it means that you can use ||operator with values that are not booleans. Though it makes no sense, you can use this operator with for example a function and an object:

JavaScript 有点不同,因为它是一种松散类型的语言。在这种情况下,这意味着您可以使用||带有非布尔值的运算符。虽然没有意义,但您可以将此运算符用于例如函数和对象:

(function(){}) || {}

What happens there?

那里会发生什么?

If values are not boolean, JavaScript makes implicit conversion to boolean. It means that if the value is falsey (e.g. 0, "", null, undefined(see also All falsey values in JavaScript)), it will be treated as false; otherwise it's treated as true.

如果值不是布尔值,JavaScript 会隐式转换为 boolean。这意味着如果值是假的(例如0, "", null, undefined(另请参阅JavaScript 中的所有假值)),它将被视为false; 否则它被视为true.

So the above example should give true, because empty function is truthy. Well, it doesn't. It returns the empty function. That's because JavaScript's ||operator doesn't work as I wrote at the beginning. It works the following way:

所以上面的例子应该给出true,因为空函数是真的。好吧,它没有。它返回空函数。那是因为 JavaScript 的||操作符不像我一开始写的那样工作。它的工作方式如下:

  • If the first value is falsey, it returns the second value.
  • If the first value is truthy, it returns the first value.
  • 如果第一个值为falsey,则返回第二个值
  • 如果第一个值是值,则返回第一个值

Surprised? Actually, it's "compatible" with the traditional ||operator. It could be written as following function:

惊讶?实际上,它与传统||运算符“兼容” 。可以写成如下函数:

function or(x, y) {
  if (x) {
    return x;
  } else {
    return y;
  }
}

If you pass a truthy value as x, it returns x, that is, a truthy value. So if you use it later in ifclause:

如果您将真值作为 传递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*/));

you get "Either x or y is truthy.".

你得到"Either x or y is truthy."

If xwas falsey, eitherXorYwould be y. In this case you would get the "Either x or y is truthy."if ywas truthy; otherwise you'd get "Neither x nor y is truthy".

如果x是假的,eitherXorY将是y。在这种情况下,您会得到"Either x or y is truthy."ify为真;否则你会得到"Neither x nor y is truthy".

The actual question

实际问题

Now, when you know how ||operator works, you can probably make out by yourself what does x = x || ymean. If xis truthy, xis assigned to x, so actually nothing happens; otherwise yis assigned to x. It is commonly used to define default parameters in functions. However, it is often considered a bad programming practice, because it prevents you from passing a falsey value (which is not necessarily undefinedor null) as a parameter. Consider following example:

现在,当您知道||operator 的工作原理时,您可能会自己弄明白x = x || y是什么意思。如果x为真,x则分配给x,因此实际上什么也没发生;否则y分配给x。它通常用于定义函数中的默认参数。但是,它通常被认为是一种糟糕的编程习惯,因为它会阻止您将 falsey 值(不一定是undefinednull)作为参数传递。考虑以下示例:

function badFunction(/* boolean */flagA) {
  flagA = flagA || true;
  console.log("flagA is set to " + (flagA ? "true" : "false"));
}

It looks valid at the first sight. However, what would happen if you passed falseas flagAparameter (since it's boolean, i.e. can be trueor false)? It would become true.In this example, there is no way to set flagAto false.

乍一看,它看起来很有效。但是,如果您false作为flagA参数传递(因为它是布尔值,即可以是trueor false)会发生什么?它会变成true. 在这个例子中,没有办法设置flagAfalse

It would be a better idea to explicitly check whether flagAis undefined, like that:

明确检查flagAis会是一个更好的主意undefined,就像这样:

function goodFunction(/* boolean */flagA) {
  flagA = typeof flagA !== "undefined" ? flagA : true;
  console.log("flagA is set to " + (flagA ? "true" : "false"));
}

Though it's longer, it always works and it's easier to understand.

虽然它更长,但它总是有效并且更容易理解。



You can also use the ES6 syntax for default function parameters, but note that it doesn't work in older browsers (like IE). If you want to support these browsers, you should transpile your code with Babel.

您还可以将 ES6 语法用于默认函数参数,但请注意,它不适用于旧浏览器(如 IE)。如果你想支持这些浏览器,你应该使用Babel转译你的代码。

See also Logical Operators on MDN.

另请参阅MDN 上的逻辑运算符

回答by ericteubert

If title is not set, use 'ERROR' as default value.

如果未设置标题,则使用 'ERROR' 作为默认值。

More generic:

更通用:

var foobar = foo || default;

Reads: Set foobar to fooor default. You could even chain this up many times:

读取:将 foobar 设置为foodefault。你甚至可以多次链接它:

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

回答by JUST MY correct OPINION

Explaining this a little more...

稍微解释一下这个...

The ||operator is the logical-oroperator. The result is true if the first part is true and it is true if the second part is true and it is true if both parts are true. For clarity, here it is in a table:

||操作是logical-or操作。如果第一部分为真,则结果为真,如果第二部分为真,则结果为真,如果两部分都为真,则结果为真。为了清楚起见,这里有一张表:

 X | Y | X || Y 
---+---+--------
 F | F |   F    
---+---+--------
 F | T |   T    
---+---+--------
 T | F |   T    
---+---+--------
 T | T |   T    
---+---+--------

Now notice something here? If Xis true, the result is always true. So if we know that Xis true we don't have to check Yat all. Many languages thus implement "short circuit" evaluators for logical-or(and logical-andcoming from the other direction). They check the first element and if that's true they don't bother checking the second at all. The result (in logical terms) is the same, but in terms of execution there's potentially a huge difference if the second element is expensive to calculate.

现在注意到这里的一些东西了吗?如果X为真,则结果始终为真。因此,如果我们知道这X是真的,我们根本不必检查Y。因此,许多语言为逻辑- or(和and来自另一个方向的逻辑-)实现了“短路”评估器。他们检查第一个元素,如果这是真的,他们根本不会检查第二个元素。结果(在逻辑方面)是相同的,但在执行方面,如果第二个元素的计算成本很高,则可能存在巨大差异。

So what does this have to do with your example?

那么这和你的例子有什么关系呢?

var title   = title || 'Error';

Let's look at that. The titleelement is passed in to your function. In JavaScript if you don't pass in a parameter, it defaults to a null value. Also in JavaScript if your variable is a null value it is considered to be false by the logical operators. So if this function is called with a title given, it is a non-false value and thus assigned to the local variable. If, however, it is not given a value, it is a null value and thus false. The logical-oroperator then evaluates the second expression and returns 'Error' instead. So now the local variable is given the value 'Error'.

让我们来看看。该title元素被传递给您的函数。在 JavaScript 中,如果不传入参数,则默认为空值。同样在 JavaScript 中,如果您的变量是空值,则逻辑运算符将其视为假。因此,如果在给定标题的情况下调用此函数,则它是一个非假值,因此分配给局部变量。然而,如果它没有被赋予一个值,它就是一个空值,因此是假的。然后逻辑or运算符计算第二个表达式并返回'Error'。所以现在局部变量被赋予值“错误”。

This works because of the implementation of logical expressions in JavaScript. It doesn't return a proper boolean value (trueor false) but instead returns the value it was given under some rules as to what's considered equivalent to trueand what's considered equivalent to false. Look up your JavaScript reference to learn what JavaScript considers to be true or false in boolean contexts.

这是因为在 JavaScript 中实现了逻辑表达式。它不返回正确的布尔值(truefalse),而是返回根据某些规则给出的值,即什么被认为是等价于true什么被认为是等价于false。查找您的 JavaScript 参考以了解 JavaScript 在布尔上下文中认为是对还是错。

回答by Morfildur

Basically it checks if the value before the || evaluates to true, if yes, it takes this value, if not, it takes the value after the ||.

基本上它会检查 || 之前的值是否 计算结果为真,如果是,则取此值,如果不是,则取 || 后的值。

Values for which it will take the value after the || (as far as i remember):

它将取 || 之后的值的值 (就目前我所记得的):

  • undefined
  • false
  • 0
  • '' (Null or Null string)
  • 不明确的
  • 错误的
  • 0
  • ''(空或空字符串)

回答by Juriy

Double pipe stands for logical "OR". This is not really the case when the "parameter not set", since strictly in the javascript if you have code like this:

双管代表逻辑“或”。当“未设置参数”时,情况并非如此,因为如果您有这样的代码,则严格在 javascript 中:

function foo(par) {
}

Then calls

然后调用

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

are not equivalent.

不等价。

Double pipe (||) will cast the first argument to boolean and if resulting boolean is true - do the assignment otherwise it will assign the right part.

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

This matters if you check for unset parameter.

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

Let's say, we have a function setSalary that has one optional parameter. If user does not supply the parameter then the default value of 10 should be used.

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

if you do the check like this:

如果你做这样的检查:

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

This will give unexpected result on call like

这将在通话中产生意想不到的结果,例如

setSalary(0) 

It will still set the 10 following the flow described above.

它仍将按照上述流程设置 10。

回答by Azrantha

Whilst Cletus' answeris correct, I feel more detail should be added in regards to "evaluates to false" in JavaScript.

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

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

Is not just checking if title/msg has been provided, but also if either of them are falsy. i.e. one of the following:

不仅要检查是否提供了 title/msg,还要检查它们中的任何一个是否为false。即以下之一:

  • false.
  • 0 (zero)
  • "" (empty string)
  • null.
  • undefined.
  • NaN (a special Number value meaning Not-a-Number!)
  • 错误的。
  • 0(零)
  • ""(空字符串)
  • 空值。
  • 不明确的。
  • NaN(一个特殊的数值,表示非数值!)

So in the line

所以在行

var title = title || 'Error';

If title is truthy (i.e., not falsy, so title = "titleMessage" etc.) then the Boolean OR (||) operator has found one 'true' value, which means it evaluates to true, so it short-circuits and returns the true value (title).

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

If title is falsy (i.e. one of the list above), then the Boolean OR (||) operator has found a 'false' value, and now needs to evaluate the other part of the operator, 'Error', which evaluates to true, and is hence returned.

如果 title 为假(即上面的列表之一),则布尔 OR (||) 运算符已找到“假”值,现在需要计算运算符的另一部分“错误”,其计算结果为真,因此被返回。

It would also seem (after some quick firebug console experimentation) if both sides of the operator evaluate to false, it returns the second 'falsy' operator.

看起来(在一些快速的萤火虫控制台实验之后)如果运算符的两边都评估为假,它会返回第二个“假”运算符。

i.e.

IE

return ("" || undefined)

returns undefined, this is probably to allow you to use the behavior asked about in this question when trying to default title/message to "". i.e. after running

返回未定义,这可能是为了让您在尝试将标题/消息默认为“”时使用此问题中询问的行为。即运行后

var foo = undefined
foo = foo || ""

foo would be set to ""

foo 将设置为“”

回答by Mohsen Alizadeh

To add some explanation to all said before me, I should give you some examples to understand logical concepts.

为了对我之前所说的所有内容进行一些解释,我应该举一些例子来理解逻辑概念。

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

It means if the left side evaluated as a true statement it will be finished and the left side will be returned and assigned to the variable. in other cases the right side will be returned and assigned.

这意味着如果左侧评估为真语句,它将被完成,左侧将被返回并分配给变量。在其他情况下,右侧将被退回和分配。

Andoperator have the opposite structure like below.

运营商有相反的结构如下图所示。

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

回答by choise

double pipe operator

双管操作员

is this example usefull?

这个例子有用吗?

var section = document.getElementById('special');
if(!section){
     section = document.getElementById('main');
}

can also be

也可以是

var section = document.getElementById('special') || document.getElementById('main');

回答by Shivang Gupta

||is the boolean OR operator. As in javascript, undefined, null, 0, falseare considered as falsyvalues.

|| 是布尔 OR 运算符。由于在JavaScript中,不确定,NULL,0,假被视为falsy值。

It simply means

简单来说就是

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"