【问题标题】:Using the ternary operator with string concatenation将三元运算符与字符串连接一起使用
【发布时间】:2012-10-11 20:20:24
【问题描述】:
alert("test: "+(1==2)?'hello':'world');

这应该在屏幕上显示'world',因为 1 不等于 2。

怎么会提示'hello'

【问题讨论】:

    标签: javascript


    【解决方案1】:

    尝试将你的括号包裹在操作周围

    alert("test: "+ (1 == 2 ? 'hello' : 'world'));
    

    演示:http://jsfiddle.net/hunter/K3PKx/


    这是在做什么:

    alert("test: "+(1==2)?'hello':'world');
    

    "test: " + (1==2) 评估为true,输出'hello'

    【讨论】:

      【解决方案2】:

      你需要添加一些额外的括号:

      alert("test: " + ((1 == 2) ? "hello" : "world"));
      

      【讨论】:

        【解决方案3】:

        使用 ES6 你可以使用Template Literals:

        alert(`test: ${1 === 2 ? 'hello' : 'world'}`);

        【讨论】:

          【解决方案4】:

          运算符优先级

          所有运算符都有所谓的precedence. 这就是语言确定order of operations 的方式。优先级较高的运算符将在优先级较低的运算符之前进行评估。操作顺序是允许表达式以正确顺序执行的原因。

          例如,

          1 + 2 * 3 == 1 + 6 == 7
          

          因为* 的优先级高于+。没有优先级,你会得到

          1 + 2 * 3 == 3 * 3 == 9
          

          +?:

          在 JavaScript 中,+ operator has higher precedence than the ?: operator. 这意味着连接将在评估三元中的条件之前发生。这可能会导致一些奇怪的结果。

          注意:运算符的关联性和优先级可以在语言之间改变。例如,在 JavaScript 中,?: 运算符是右关联的,但它是 left associative in PHP。这些相同的比较将在这些语言之间产生不同的结果。

          var variable, str;
          
          // Equality operators have higher precedence than ?: but lower than +
          // so the below expression breaks down like this:
          //   ("A" + variable) !== undefined ? "B" : ("C" + "D")
          //   "Aundefined" !== undefined ? "B" : "CD"
          //   true ? "B" : "CD"
          //   "B"
          str = "A" + variable !== undefined ? "B" : "C" + "D";
          console.log(str);
          
          // For the same reason as above, you get a strange result here.
          // Here's how we break it down:
          //   ("A" + variable) === undefined ? "B" : ("C" + "D")
          //   "Aundefined" === undefined ? "B" : "CD"
          //   false ? "B" : "CD"
          //   "CD"
          str = "A" + variable === undefined ? "B" : "C" + "D";
          console.log(str);

          无论条件如何,都会发生同样类型的问题:

          // Check for undefined
          var animal;
          // Expected: "The animal does not exist", actual: undefined
          console.log("The animal " + animal === undefined ? "does not exist" : animal);
          
          // Expected: "The animal undefined", actual: "does not exist"
          console.log("The animal " + animal !== undefined ? "does not exist" : animal);
          
          // Check for null
          animal = null;
          // Expected: "The animal does not exist", actual: null
          console.log("The animal " + animal === null ? "does not exist" : animal);
          
          // Expected: "The animal null", actual: "does not exist"
          console.log("The animal " + animal !== null ? "does not exist" : animal);
          
          // Check for property
          animal = {};
          // Expected: "This animal doesn't have a type", actual: undefined
          console.log("The animal " + animal.hasOwnProperty('type') ? animal.type : "doesn't have a type");
          
          animal.type = 'is a dog';
          // Expected: "This animal is a dog", actual: "is a dog"
          console.log("The animal " + animal.hasOwnProperty('type') ? animal.type : "doesn't have a type");

          解决方案

          使用这些相同的优先级规则,我们知道括号 (( ... )) 具有任何其他运算符的最高优先级。通过在括号内对操作进行分组,将首先评估这些操作。这以递归方式工作,允许您在更深的括号内进一步分组操作。

          鉴于此,您可以在括号内编写三元表达式以获得所需的结果。

          var animal;
          console.log( "The animal " + (animal === undefined ? "does not exist" : animal) );
          console.log( "The animal " + (animal !== undefined ? "does not exist" : animal) );
          
          animal = null;
          console.log( "The animal " + (animal === null ? "does not exist" : animal) );
          console.log("The animal " + (animal !== null ? "does not exist" : animal) );
          
          animal = {};
          console.log( "The animal " + (animal.hasOwnProperty('type') ? animal.type : "doesn't have a type") );
          
          animal.type = 'is a dog';
          console.log( "The animal " + (animal.hasOwnProperty('type') ? animal.type : "doesn't have a type") );

          一般来说,最好也将您的条件用括号括起来。这样,在使用较低优先级的运算符生成条件时,您将获得正确的值。

          // Assignment without parentheses
          var x = 0;
          console.log( x += 2 ? 'x is 2' : 'x is not 2' );
          
          // Assignment with parentheses
          x = 0;
          console.log( (x += 2) ? 'x is 2' : 'x is not 2' );

          【讨论】:

            【解决方案5】:

            两个提交的答案都是正确的,你需要加括号。我想我会简单谈谈原因。

            alert("test: "+(1==2)?'hello':'world');
            

            当解析器遇到一个语句时,它会开始递归地将它分解成越来越小的块。

            在这种情况下,它首先遇到的是一个函数:alert。解析器将立即查看alert 的参数,并开始单独解析每个参数。这个函数只有一个参数,"test: "+(1==2)?'hello':'world',这是一个简单的第一步。

            在这个级别,我们可以将我们的语句分解为一系列二进制比较。 Javascript 解析器从左到右形成二进制对(当操作值的顺序相同时)。我们的潜在候选人是"test: "(1==2)'hello''world',运营商为+?:。解析器将首先尝试添加"test: "(1==2)。为此,它必须首先评估语句(1==2)(其评估结果为false)。 + 运算符导致与字符串连接,并强制所有原始变量也尝试将自己表示为字符串。 false 计算为字符串 "false" 创建语句 "test: false"

            解析器现在已准备好评估三元组的第一部分:"test: false"?。在 Javascript 中,所有非空字符串的计算结果为 true,通过三元运算符的测试并选择第一个选项 "hello"

            通过在原始语句中添加一些额外的括号:

            alert("test: " + ((1 == 2) ? 'hello' : 'world'));
            

            我们告诉解析器我们要在连接之前评估三元运算符。

            【讨论】:

              猜你喜欢
              • 2020-07-23
              • 2010-11-21
              • 2020-10-21
              • 2019-01-09
              • 1970-01-01
              • 2020-06-10
              • 2015-06-09
              相关资源
              最近更新 更多