简体   繁体   English

使用带有字符串连接的三元运算符

[英]Using the ternary operator with string concatenation

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

This should show me 'world' on the screen since 1 is not equal to 2. 这应该在屏幕上显示'world' ,因为1不等于2。

How come it alerts 'hello' ? 它怎么警告'hello'

Try wrapping your parens around the operation 尝试围绕操作包裹你的parens

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

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


what this is doing: 这是做什么的:

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

is evaluating "test: " + (1==2) as true which outputs 'hello' 正在评估"test: " + (1==2)true ,输出'hello'

Both of the submitted answers are correct, you need to add parentheses. 两个提交的答案都是正确的,您需要添加括号。 I figured I'd talk briefly about why. 我想我会简要谈谈为什么。

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

When the parser encounters a statement, it will begin recursively breaking it down into smaller and smaller chunks. 当解析器遇到一个语句时,它将开始递归地将其分解为越来越小的块。

In this case, the first thing it encounters is a function: alert . 在这种情况下,它遇到的第一件事是一个函数: alert Immediately the parser will look at alert 's arguments, and begin parsing each of them individually. 解析器会立即查看alert的参数,并开始分别解析每个参数。 This function only has one argument, "test: "+(1==2)?'hello':'world' , making it an easy first step. 这个函数只有一个参数, "test: "+(1==2)?'hello':'world' ,这是第一步。

At this level we can break our statement down into a series of binary comparisons. 在这个级别,我们可以将我们的陈述分解为一系列二进制比较。 Javascript parsers form binary pairs from left-to-right (when order of operation values are the same). Javascript解析器从左到右形成二进制对(当操作值的顺序相同时)。 Our potential candidates are "test: " , (1==2) , 'hello' and 'world' with operators + , ? 我们的潜在候选人是"test: "(1==2)'hello''world'与运营商+ ? and : . 并且: The parser will first attempt to add "test: " and (1==2) . 解析器将首先尝试添加"test: "(1==2) To do this it must first evaluate the statement (1==2) (which evaluates to false ). 要做到这一点,它必须首先评估语句(1==2) (评估为false )。 The + operator causes concatenation with strings and forces all primitive variables to attempt to represent themselves as strings as well. +运算符导致与字符串连接,并强制所有原始变量尝试将自己表示为字符串。 false evaluates as the string "false" creating the statement "test: false" . false计算为字符串"false"创建语句"test: false"

The parser is now ready to evaluate the first part of the ternary: "test: false"? 解析器现在准备好评估三元组的第一部分: "test: false"? . In Javascript, all non-empty strings evaluate to true , passing the ternary operator's test and picking the first option "hello" . 在Javascript中,所有非空字符串都计算为true ,通过三元运算符的测试并选择第一个选项"hello"

By throwing a few extra parenthesis into the original statement: 通过在原始语句中添加一些额外的括号:

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

We tell the parser that we want to evaluate the ternary operator BEFORE concatenation. 我们告诉解析器我们要评估三元运算符BEFORE连接。

Operator Precedence 运营商优先权

All operators have what's known as precedence. 所有运营商都拥有所谓的优先权。 This is how the language determines the order of operations . 这就是语言决定操作顺序的方式 Operators with higher precedence will be evaluated before those with lower precedence. 优先级较高的运算符将在优先级较低的运算符之前进行求值。 Order of operations is what allows expressions to be executed in the correct order. 操作顺序允许表达式以正确的顺序执行。

For example, 例如,

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

because * has a higher precedence than + . 因为*的优先级高于+ Without precedence, you would get 没有优先权,你会得到

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

+ vs. ?: + vs. ?:

In JavaScript, the + operator has higher precedence than the ?: operator. 在JavaScript中, +运算符的优先级高于?:运算符。 This means that concatenation will take place before the condition in a ternary is evaluated. 这意味着在评估三元中的条件之前将进行连接。 This can lead to some strange results. 这可能会导致一些奇怪的结果。

Note: operator associativity and precedence can change between languages. 注意:运算符关联性和优先级可以在不同语言之间更改。 For example, in JavaScript the ?: operator is right associative but it's left associative in PHP . 例如,在JavaScript中, ?:运算符是右关联的,但它在PHP中左关联的 These same comparisons will produce different results between these languages. 这些相同的比较将在这些语言之间产生不同的结果。

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

This same type of problem will happen no matter what the condition is: 无论条件如何,都会发生同样的问题:

 // 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"); 

Solution

Using these same precedence rules, we know that parentheses ( ( ... ) ) have the highest precedence of any other operators. 使用这些相同的优先级规则,我们知道括号( ( ... ) )具有任何其他运算符的最高优先级。 By grouping operations inside of parentheses, those operations will be evaluated first. 通过对括号内的操作进行分组,将首先评估这些操作。 This works recursively, allowing you to further group operations inside of deeper sets of parentheses. 它以递归方式工作,允许您在更深的括号内进一步分组操作。

Given this, you can write your ternary expressions inside of parentheses to get the desired result. 鉴于此,您可以在括号内编写三元表达式以获得所需的结果。

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

In general, it's a good idea to wrap your condition in parentheses as well. 一般来说,将条件包装在括号中也是个好主意。 That way you will get the correct value when generating the condition with operators of a lower precedence. 这样,在使用较低优先级的运算符生成条件时,您将获得正确的值。

 // 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' ); 

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

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

使用ES6,您可以使用模板文字

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM