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

发布于 2024-08-31 22:20:14 字数 252 浏览 5 评论 0原文

我正在调试一些 JavaScript,但无法解释这个 || 的作用:

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

为什么这个人使用 var title = title || “错误”?有时我也会看到它没有 var 声明。

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

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

Why is this guy using var title = title || 'ERROR'? I sometimes see it without a var declaration as well.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

习惯成性 2024-09-07 22:20:14

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

双管道运算符 (||) 是逻辑 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  

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

JavaScript 中有何不同?

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

(function(){}) || {}

那里会发生什么?

如果值不是布尔值,JavaScript 会隐式转换为布尔值。这意味着如果该值为 false(例如 0""nullundefined(另请参阅< a href="https://stackoverflow.com/questions/19839952/all-falsey-values-in-javascript">JavaScript 中的所有 false 值)),它将被视为 false;否则它被视为true

所以上面的例子应该给出true,因为空函数是true。嗯,事实并非如此。它返回空函数。这是因为 JavaScript 的 || 运算符不能像我一开始写的那样工作。它的工作方式如下:

  • 如果第一个值是falsey,则返回第二个值
  • 如果第一个值是,则返回第一个值

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

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 true.”

如果x为假,eitherXorY将为y。在这种情况下,如果 y 为真,您将得到“X 或 y 为真。”;否则你会得到“x 和 y 都不是真的”

实际问题

现在,当您知道 || 运算符如何工作时,您可能可以自己弄清楚 x = x || 的作用是什么。 y 的意思是。如果x为真,则x被赋值给x,所以实际上什么也没有发生;否则y 被分配给x。它通常用于定义函数中的默认参数。但是,它通常被认为是一种糟糕的编程实践,因为它会阻止您传递错误值(不一定是 undefinednull)作为参数。考虑以下示例:

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

乍一看似乎很有效。但是,如果您将 false 作为 flagA 参数传递(因为它是布尔值,即可以是 truefalse ),会发生什么>)? 它将变为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 上的逻辑运算符

What is the double pipe operator (||)?

The double pipe operator (||) is the logical OR operator . In most languages it works the following way:

  • If the first value is false, it checks the second value. If that's true, it returns true and if the second value is false, it returns false.
  • If the first value is true, it always returns true, no matter what the second value is.

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 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:

(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.

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:

  • If the first value is falsey, it returns the second value.
  • If the first value is truthy, it returns the first value.

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 if clause:

(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.".

If x was falsey, eitherXorY would be y. In this case you would get the "Either x or y is truthy." if y was truthy; otherwise you'd get "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 || y mean. If x is truthy, x is assigned to x, so actually nothing happens; otherwise y is 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 undefined or null) as a parameter. Consider following example:

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 false as flagA parameter (since it's boolean, i.e. can be true or false)? It would become true. In this example, there is no way to set flagA to false.

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

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.

See also Logical Operators on MDN.

初相遇 2024-09-07 22:20:14

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

这是写作的简写:

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

这种布尔表达式的简写技巧在 Perl 中也很常见。对于表达式:

a OR b

如果 abtrue,则计算结果为 true。因此,如果 a 为 true,则根本不需要检查 b。这称为短路布尔评估,因此:

var title = title || "Error";

基本上检查 title 的计算结果是否为 false。如果是,则“返回”“Error”,否则返回title

It means the title argument is optional. So if you call the method with no arguments it will use a default value of "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:

a OR b

it evaluates to true if either a or b is true. So if a is true you don't need to check b at all. This is called short-circuit boolean evaluation so:

var title = title || "Error";

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

舞袖。长 2024-09-07 22:20:14

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

更通用:

var foobar = foo || default;

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

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

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

More generic:

var foobar = foo || default;

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

var foobar = foo || bar || something || 42;
薄荷梦 2024-09-07 22:20:14

对此进行更多解释...

|| 运算符是逻辑-or 运算符。如果第一部分为真,则结果为真;如果第二部分为真,则结果为真;如果两个部分都为真,则结果为真。为了清楚起见,将其放在表格中:

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

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

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

var title   = title || 'Error';

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

这是因为 JavaScript 中逻辑表达式的实现。它不会返回正确的布尔值(truefalse),而是返回根据某些规则给出的值,这些规则被认为相当于 true< /code> 以及被认为等同于 false 的内容。查找 JavaScript 参考以了解 JavaScript 在布尔上下文中认为什么是 true 或 false。

Explaining this a little more...

The || operator is the logical-or operator. 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:

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

Now notice something here? If X is true, the result is always true. So if we know that X is true we don't have to check Y at all. Many languages thus implement "short circuit" evaluators for logical-or (and logical-and coming 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.

So what does this have to do with your example?

var title   = title || 'Error';

Let's look at that. The title element 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-or operator then evaluates the second expression and returns 'Error' instead. So now the local variable is given the value 'Error'.

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

掩于岁月 2024-09-07 22:20:14

|| 是布尔OR 运算符。与 JavaScript 中一样,undefined、null、0、false 被视为 falsy 值。

它只是意味着

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"

|| is the boolean OR operator. As in JavaScript, undefined, null, 0, false are considered as falsy values.

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"
清秋悲枫 2024-09-07 22:20:14

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

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

  • undefined
  • false
  • 0
  • '' (Null 或 Null 字符串)

Basically, it checks if the value before the || evaluates to true. If yes, it takes this value, and 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)
野鹿林 2024-09-07 22:20:14

虽然 Cletus 的答案是正确的,但我认为应该在 JavaScript 中添加有关“评估为 false”的更多细节。

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

不仅检查是否提供了 title/msg,还检查其中任何一个是否 虚假的。即以下之一:

  • 错误。
  • 0(零)
  • ""(空字符串)
  • 空。
  • 未定义。
  • NaN(特殊的数字值,表示非数字!)

因此,在 If title is true (ie, not false, so title = "titleMessage" etc.) 行中,

var title = title || 'Error';

布尔 OR (||) 运算符找到了一个 ' true' 值,这意味着它的计算结果为 true,因此它会短路并返回 true 值(标题)。

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

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

return ("" || undefined)

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

var foo = undefined
foo = foo || ""

foo 后将被设置为“”

Whilst Cletus' answer is correct, I feel more detail should be added in regards to "evaluates to false" in 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:

  • false.
  • 0 (zero)
  • "" (empty string)
  • null.
  • undefined.
  • NaN (a special Number value meaning Not-a-Number!)

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).

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.

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.

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 ""

洋洋洒洒 2024-09-07 22:20:14

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

function foo(par) {
}

那么调用

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

是不等效的。

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

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

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

如果您像这样进行检查:

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

这将为如下调用提供意外结果:

setSalary(0)

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

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

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 the resulting Boolean is true - do the assignment, otherwise it will assign the right part.

This matters if you check for unset parameter.

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

If you do the check like this:

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

This will give an unexpected result for a call like:

setSalary(0)

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

数理化全能战士 2024-09-07 22:20:14

双管道运算符

这个例子可能有用:

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

它也可以是:

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

Double pipe operator

This example may be useful:

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

It can also be:

var section = document.getElementById('special') || document.getElementById('main');
余生一个溪 2024-09-07 22:20:14

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

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

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

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

var name = false && "Mohsen" # name equals to false
var family = true && "Alizadeh" # family equals to 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.

And operator have the opposite structure like below.

var name = false && "Mohsen" # name equals to false
var family = true && "Alizadeh" # family equals to Alizadeh
云淡风轻 2024-09-07 22:20:14

引用:“构造 x = x || y 是什么意思?”

分配默认值。

这意味着为 x 提供 y 的默认值
如果 x 仍在等待其值但尚未收到它或故意省略以便回退到默认值。

Quote: "What does the construct x = x || y mean?"

Assigning a default value.

This means providing a default value of y to x,
in case x is still waiting for its value but hasn't received it yet or was deliberately omitted in order to fall back to a default.

泪意 2024-09-07 22:20:14

我还必须补充一件事:这种速记是令人厌恶的。它滥用意外的解释器优化(如果第一个操作为真,则不关心第二个操作)来控制分配。该用途与操作员的目的无关。我认为永远不应该使用它。

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

var title = title?title:'Error';

这使用单行条件运算来实现其正确目的。它仍然诚实地玩着难看的游戏,但这就是适合你的 JavaScript。

And I have to add one more thing: This bit of shorthand is an abomination. It misuses an accidental interpreter optimization (not bothering with the second operation if the first is truthy) to control an assignment. That use has nothing to do with the purpose of the operator. I do not believe it should ever be used.

I prefer the ternary operator for initialization, for example,

var title = title?title:'Error';

This uses a one-line conditional operation for its correct purpose. It still plays unsightly games with truthiness but, that's JavaScript for you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文