JavaScript中的自动类型转换

时间:2012-10-19 20:38:37

标签: javascript

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

var x = 10 + 10;

x的值为20

x = 10 + '10';

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

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

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


以下表达式会发生什么。

x = '100' - -'150';    

x的值为250。这似乎也是显而易见的,但这种表达似乎与以下表达式相同。

x = '100' +'150';

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


编辑:

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

5 个答案:

答案 0 :(得分:3)

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

由于你不能减去一个字符串(NaN),然后JS取"100"并编号,然后运行100 - -150,即250

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

答案 1 :(得分:3)

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

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

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

如果JS看到'100' - -'150',它会认为,“嘿,我看到字符串带有 - ..我不能真正做任何字符串函数,所以我会将它们视为数字......”

答案 2 :(得分:2)

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

x = '100' - -'150';

相当于

x = '100' - -150;

进一步减少到

x = 100 - -150;

因为二进制-运算符也总是将其操作数转换为Number(s.11.6.2)。

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

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

答案 3 :(得分:1)

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

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

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

答案 4 :(得分: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>