8

JavaScript 中的以下所有表达式非常明显。

var x = 10 + 10;

x值为20

x = 10 + '10';

x在这种情况下的值是1010因为+运算符被重载。如果任何操作数是字符串类型,则进行字符串连接,如果所有操作数都是数字,则执行加法。

x = 10 - 10;
x = 10 - '10';

在这两种情况下,值x将是0因为-运算符没有以这种方式重载,并且所有操作数都转换为数字,如果它们不是在执行实际减法之前(你可以澄清,如果无论如何我错了) .


下面的表达式会发生什么。

x = '100' - -'150';    

x值为250。这似乎也很明显,但这个表达式在某种程度上似乎等同于以下表达式。

x = '100' +'150';

如果是这种情况,那么这两个字符串将被连接并分配100150x. 那么为什么在这种情况下执行加法呢?


编辑 :

+'10' + 5返回15'a' + + 'b'返回aNaN。有谁知道为什么?

4

5 回答 5

3

在您的情况下- -,首先不会评估为等效于+. -"150"被评估为一个数字,因此成为-150.

因为你不能减去一个字符串 ( NaN),所以 JS 然后取"100"一个数字,然后它运行100--150即 250。

关键是你不能减去类型字符串,所以它将这些字符串转换为数字。

于 2012-10-19T20:45:07.560 回答
3

+ 和 - 运算符对字符串的响应不同。

+ 运算符连接字符串;但是, - 运算符不会执行相反的操作(拆分字符串)。

因此,如果 JavaScript 看到'100' +'150',它会认为“嘿,我看到带有 + 的字符串......我可以将它们连接起来。”

如果 JS 看到'100' - -'150',它会想,“嘿,我看到字符串带有 - .. 我真的不能做任何字符串函数,所以我会把它们当作数字来对待......”

于 2012-10-19T20:50:09.467 回答
2

一元运算-符始终将其操作数转换为数字(ECMA-262 s. 11.4.6)。所以

x = '100' - -'150';

相当于

x = '100' - -150;

这进一步减少到

x = 100 - -150;

因为二元-运算符也总是将其操作数转换为数字(第 11.6.2 节)。

相比之下,一元运算+符将其操作数转换为字符串,如果其中任何一个已经是字符串(s. 11.6.1)。

您可以在http://www.ecma-international.org/publications/standards/Ecma-262.htm找到 ECMAscript 的完整规范(因此也​​是 Javascript 的核心)。

于 2012-10-19T20:49:58.350 回答
1

如果 JS 看到在字符串上使用减号运算符,它首先尝试将其类型转换为数字,然后评估表达式,因为减号运算符仅用于算术运算。加号运算符可能意味着首先连接然后添加。

在其他一些弱类型语言(如 PHP)中,这种歧义通过使用两个不同的运算符进行连接和加法来消除。

然而,对字符串使用算术的正确方法是将它们手动转换为数字(使用parseInt)。

于 2012-10-19T20:55:06.557 回答
1

附录

此表显示了各种转换的结果,其中变量s=stringn=number. 您还可以使用提供的代码片段尝试自己的值。

这个帖子回答了我的一些问题。所以我发布我的测试结果来帮助其他到达这里寻找答案的人。

╔═════════════╦═══════════╦════════╗
║ INPUT       ║ VALUE     ║ TYPEOF ║
╠═════════════╬═══════════╬════════╣
║ n           ║ 11.5      ║ number ║
║ s           ║ -1.5      ║ string ║
║ s - 0       ║ -1.5      ║ number ║
║ n + s - 0   ║ NaN       ║ error  ║
║ n + (s - 0) ║ 10        ║ number ║
║ s + 0       ║ -1.50     ║ string ║
║ n + s + 0   ║ 11.5-1.50 ║ string ║
║ n + (s + 0) ║ 11.5-1.50 ║ string ║
║ n + s       ║ 11.5-1.5  ║ string ║
║ s + n       ║ -1.511.5  ║ string ║
║ +s + n      ║ 10        ║ number ║
║ n + +s      ║ 10        ║ number ║
║ n++s        ║           ║ error  ║
║ n+(+s)      ║ 10        ║ number ║
║ Number(s)+n ║ 10        ║ number ║
╚═════════════╩═══════════╩════════╝

var n = 11.5, s = '-1.5';

add('n');
add('s');
add('s - 0');
add('n + s - 0');
add('n + (s - 0)');
add('s + 0');
add('n + s + 0');
add('n + (s + 0)');
add('n + s');
add('s + n');
add('+s + n');
add('n + +s');
add('n++s');
add('n+(+s)');
add('Number(s) + n');

function add(eq) {
	var v, r, t;
  try { v = eval(eq); t = typeof v; } catch(e) { v = ''; t = 'error';}
  if (t=='number' && isNaN(v)) t = 'error';
  r = window.stdout.insertRow();
  r.className = t;
  r.insertCell().innerHTML = eq;
  r.insertCell().innerHTML = v;
  r.insertCell().innerHTML = t;
}
table { border-collapse: collapse; font-family: sans-serif; }
td { min-width: 5em; padding: 2px; border: 1px dimgray solid; text-align: right; }
tr {   background-color: lightgreen; }
.string { background-color: lightyellow; }
.error { background-color: pink; }
<table id="stdout"><caption>Type Conversion Results</caption></table>

于 2016-03-20T21:39:53.293 回答