代码之家  ›  专栏  ›  技术社区  ›  opHASnoNAME

构造x=x_y是什么意思?

  •  200
  • opHASnoNAME  · 技术社区  · 15 年前

    我正在调试一些javascript,无法解释这是什么 || 做?

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

    有人能给我个提示吗,为什么这个人要用 var title = title || 'ERROR' ?我有时看到它没有 var 声明也一样。

    11 回复  |  直到 6 年前
        1
  •  177
  •   cletus    15 年前

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

    这是书写的简写:

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

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

    a OR b
    

    它评估为 true 如果任一 a b . 所以如果 是真的,你不需要检查 完全。这被称为短路布尔计算,因此:

    var title = title || "Error";
    

    基本上检查 标题 评估为 false . 如果是,它会“返回” “错误” ,否则返回 标题 .

        2
  •  147
  •   Michał Perłakowski    6 年前

    双管接线员是什么( || )?

    双管操作员( γ 符合逻辑的 OR 操作人员 . 在 大多数语言 其工作方式如下:

    • 如果第一个值是 false ,它检查第二个值。如果是 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会 隐式对话到布尔值 . 这意味着如果价值是虚假的(例如 0 , "" , null , undefined (也见) All falsey values in JavaScript ))将被视为 否则它会被视为 .

    所以上面的例子应该给出 因为空函数是真实的。嗯,它没有。它返回空函数。这是因为javascript γ 接线员不像我一开始写的那样工作。其工作方式如下:

    • 如果第一个值是 法西 它回来了 第二个值 .
    • 如果第一个值是 诚实的 它回来了 第一值 .

    惊讶?实际上,它与传统的 γ 操作员。它可以写成以下函数:

    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 . 在这种情况下,你会得到 “X或Y都是真实的。” 如果 Y 是真实的,否则你会 "Neither x nor y is truthy" .

    实际问题

    现在,当你知道如何 γ 接线员工作,你可能自己知道是什么 x = x || y 平均。如果 X 真的, X 分配给 X ,所以实际上什么都没有发生;否则 Y 分配给 X . 它通常用于定义函数中的默认参数。然而,它通常被认为是 糟糕的编程实践 ,因为它阻止您传递错误的值(不一定 未定义 无效的 )作为参数。请考虑以下示例:

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

    乍一看是有效的。但是,如果你通过了 作为 flagA 参数(因为它是布尔值,即 )? 它会变成 . 在本例中,无法设置 弗拉加 .

    最好是明确地检查 弗拉加 未定义 ,像这样:

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

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


    您也可以使用 the ES6 syntax for default function parameters 但请注意,它在旧浏览器(如IE)中不起作用。如果您想支持这些浏览器,应该使用 Babel .

    也见 Logical Operators on MDN .

        3
  •  28
  •   ericteubert    12 年前

    如果未设置标题,请使用“错误”作为默认值。

    更通用:

    var foobar = foo || default;
    

    读取:将foobar设置为 foo default . 你甚至可以把这个链接很多次:

    var foobar = foo || bar || something || 42;
    
        4
  •  13
  •   JUST MY correct OPINION    15 年前

    再解释一下……

    这个 || 运算符是逻辑的- or 操作员。如果第一部分为真,则结果为真;如果第二部分为真,则结果为真;如果两部分均为真,则结果为真。为了清楚起见,这里是一个表格:

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

    注意到了吗?如果 X 是真的,结果总是真的。所以如果我们知道的话 X 是真的,我们不需要检查 Y 完全。因此,许多语言实现了逻辑的“短路”评估- (逻辑) and 来自另一个方向)。他们检查第一个元素,如果这是真的,他们根本不需要检查第二个元素。结果(逻辑上)是相同的,但在执行方面,如果第二个元素的计算成本很高,则可能存在巨大的差异。

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

    var title   = title || 'Error';
    

    让我们看看这个。这个 title 元素被传递给函数。在javascript中,如果不传递参数,则默认为空值。同样,在javascript中,如果变量是空值,则逻辑运算符认为它是假的。因此,如果用给定的标题调用这个函数,它是一个非假值,因此被分配给局部变量。但是,如果没有给定值,则为空值,因此为假。逻辑- 然后,运算符计算第二个表达式并返回“error”。所以现在局部变量的值为'error'。

    这是因为在JavaScript中实现了逻辑表达式。它没有返回正确的布尔值( true false )但返回一些规则下给定的值,这些值被认为是等价的 什么被认为等同于 . 查找您的javascript引用,了解在布尔上下文中javascript认为是对的还是错的。

        5
  •  7
  •   Juriy    15 年前

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

    function foo(par) {
    }
    

    然后调用

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

    不是等效的。

    double pipe()将第一个参数强制转换为布尔值,如果结果布尔值为true,则执行赋值,否则将分配正确的部分。

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

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

    如果您这样做:

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

    这将在调用时产生意外结果,如

    setSalary(0) 
    

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

        6
  •  7
  •   MarmiK hirra    10 年前

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

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

    • 未定义
    • “”(空或空字符串)
        7
  •  4
  •   choise    15 年前

    双管操作工

    这个例子有用吗?

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

    也可以

    var section = document.getElementById('special') || document.getElementById('main');
    
        8
  •  4
  •   Community CDub    7 年前

    同时 Cletus' answer 是的,我觉得应该在javascript中添加更多关于“评估为假”的细节。

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

    不仅检查是否提供了标题/msg,还检查是否提供了 falsy . 即以下其中一种:

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

    所以在这条线上

    var title = title || 'Error';
    

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

    如果标题不正确(即上述列表中的一个),则布尔或()运算符找到了一个“false”值,现在需要计算运算符“error”的另一部分,该部分的计算结果为true,因此返回。

    如果操作员的两边都评估为假,那么(经过一些快速的Firebug控制台实验之后),它会返回第二个“falsy”操作员。

    return ("" || undefined)
    

    返回Undefined,这可能允许您在尝试将标题/消息默认为“”时使用此问题中询问的行为。即跑步后

    var foo = undefined
    foo = foo || ""
    

    foo将设置为“”。

        9
  •  4
  •   Mohsen Alizadeh    9 年前

    为了给我之前所说的一切增加一些解释,我应该给你一些例子来理解逻辑概念。

    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
    
        10
  •  2
  •   Bekim Bacaj    9 年前

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

    指定默认值。

    这意味着 提供Y到X的默认值 , 如果X仍在等待它的值,但还没有收到它,或者故意忽略它,以便返回到默认值。

        11
  •  -5
  •   tqwhite    9 年前

    我还得再加一件事:这一点点的速记是可憎的。它错误地使用了一个意外的解释器优化(如果第一个操作是正确的,则不必担心第二个操作)来控制一个分配。这种使用与操作员的目的无关。我认为它不应该被使用。

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

    var title = title?title:'Error';
    

    它使用一行条件操作来实现正确的目的。它仍然用Truthinness玩难看的游戏,但是,这是你的javascript。