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

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

怎么会报警'hello'

4

5 回答 5

91

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

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

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


这是在做什么:

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

正在评估"test: " + (1==2)哪些true输出'hello'

于 2012-10-11T20:22:01.503 回答
18

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

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

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

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

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

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

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

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

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

于 2012-10-11T20:43:41.140 回答
7

运算符优先级

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

例如,

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

因为*具有比 更高的优先级+。没有优先权,你会得到

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

+对比?:

在 JavaScript 中,+运算符的优先级高于?:运算符。这意味着连接将在评估三元组中的条件之前发生。这可能会导致一些奇怪的结果。

注意:运算符的关联性和优先级可以在语言之间改变。例如,在 JavaScript 中,?:运算符是右关联的,但在 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' );

于 2016-08-25T15:00:12.723 回答
4

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

alert("test: " + ((1 == 2) ? "hello" : "world"));
于 2012-10-11T20:21:53.390 回答
3

使用 ES6,您可以使用Template Literals

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

于 2018-01-10T09:27:30.513 回答