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

2020/10/09 14:21 · javascript ·  · 0评论

我正在调试一些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是否为abtrue因此,如果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有何不同?

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

(function(){}) || {}

那里发生了什么?

如果值不是布尔值,则JavaScript会将隐式转换为boolean这意味着,如果该值是falsey(例如0""nullundefined(还参见在JavaScript中所有falsey值)),它将被视为false; 否则将被视为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 truthy."

如果x是假的,那eitherXorY就是y在这种情况下,您将获得"Either x or y is truthy."if ify真实的信息。否则你会得到"Neither x nor y is truthy"

实际问题

现在,当您知道||操作员的工作方式时,您可能可以自己弄清楚这x = x || y意味着什么如果x为true,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在此示例中,无法将设置flagAfalse

好像这样显式检查是否flagA为is是一个更好的主意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设置为foodefault您甚至可以将其链接很多次:

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

多解释一下...

||操作是logical-or操作。如果第一部分为true,则结果为true;如果第二部分为true,则结果为true;如果两个部分均为true,则结果为true。为了清楚起见,它在表格中:

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

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

那么,这与您的示例有什么关系?

var title   = title || 'Error';

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

由于JavaScript中逻辑表达式的实现,因此该方法有效。它不会返回正确的布尔值(truefalse),而是返回在某些规则下给出的关于等价于true和的等效值false查找您的JavaScript参考,以了解JavaScript在布尔上下文中认为正确还是错误。

双管道代表逻辑“或”。当未设置“参数”时,实际上不是这种情况,因为严格来说,如果您有这样的代码,则在javascript中:

function foo(par) {
}

然后打电话

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

不相等。

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

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

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

如果您像这样进行检查:

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

这样会给通话带来意外结果

setSalary(0) 

仍然按照上述流程设置10。

基本上,它检查||之前的值 计算结果为true,如果是,则采用该值;否则,采用||之后的值。

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

  • 未定义
  • 0
  • ''(空或空字符串)

尽管Cletus的回答是正确的,但我认为应该在JavaScript中添加更多有关“评估为假”的信息。

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

不仅检查是否已提供title / msg,还检查它们中的任何一个是否都是falsy即以下之一:

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

所以在行

var title = title || 'Error';

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

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

(在经过快速的Firebug控制台快速试验之后)如果运算符的两边都评估为false,那么它似乎还会返回第二个“ falsy”运算符。

return ("" || undefined)

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

var foo = undefined
foo = foo || ""

foo将设置为“”

双管操作员

这个例子有用吗?

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

也可以是

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

为了在我之前说的所有内容中添加一些解释,我应该给您一些示例以了解逻辑概念。

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

|| 是布尔OR运算符。与javascript中一样,undefined,null,0,false被视为虚假值。

它只是意味着

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"

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

分配默认值。

这意味着为x提供一个默认值y,以防x仍在等待其值但尚未收到它,或者为了回落为默认值而被故意省略。

而且我还必须添加一件事:这种简写是可憎的。它滥用了意外的解释器优化(如果第一个操作是真实的,则不会打扰第二个操作)来控制分配。这种使用与操作员的目的无关。我认为不应该使用它。

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

var title = title?title:'Error';

为此,使用单行条件运算即可。它仍然会像现实一样玩难看的游戏,但这就是您的Javascript。

本文地址:http://javascript.askforanswer.com/x-x-degouzaoshishenme-nideyisishi.html
文章标签: ,   ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!