chenshuhong / fullstack

我的全栈路线思维导图以及日常知识记录
MIT License
0 stars 0 forks source link

JavaScript隐式转换 #5

Open chenshuhong opened 4 years ago

chenshuhong commented 4 years ago

Boolean

数据类型 转换为true的值 转换为false的值
Boolean true false
String 任何非空字符串 ""(空字符串)
Number 任何非零数字值(包括无穷大) 0和NaN
Object 任何对象 null
Undefined - undefined

在if中会进行自动转换

Number

有 3 个函数可以把非数值转换为数值: Number()、 parseInt()和 parseFloat()。 第一个函数, 即转型函数 Number()可以用于任何数据类型,而另两个函数则专门用于把字符串转换成数值。这 3 个函数对于同样的输入会有返回不同的结果

Number()

var num1 = Number("Hello world!"); //NaN
var num2 = Number(""); //0
var num3 = Number("000011"); //11
var num4 = Number(true); //1

一元加操作符(+)的操作与 Number()函数相同

parseInt

处理整数的时候更常用的是parseInt()函数。 它会忽略字符串前面的空格,直至找到第一个非空格字符。如果第一个字符不是数字字符或者负号, parseInt()就会返回 NaN;也就是说,用 parseInt()转换空字符串会返回 NaN(Number()对空字符返回 0)。如果第一个字符是数字字符, parseInt()会继续解析第二个字符,直到解析完所有后续字符或者遇到了一个非数字字符。例如, "1234blue"会被转换为 1234,因为"blue"会被完全忽略。类似地, "22.5"会被转换为 22,因为小数点并不是有效的数字字符

如果字符串中的第一个字符是数字字符, parseInt()也能够识别出各种整数格式(即前面讨论的十进制、八进制和十六进制数)。也就是说,如果字符串以"0x"开头且后跟数字字符,就会将其当作一个十六进制整数;如果字符串以"0"开头且后跟数字字符,则会将其当作一个八进制数来解析。

var num1 = parseInt("1234blue"); // 1234
var num2 = parseInt(""); // NaN
var num3 = parseInt("0xA"); // 10(十六进制数)
var num4 = parseInt(22.5); // 22
var num5 = parseInt("070"); // 56(八进制数)
var num6 = parseInt("70"); // 70(十进制数)
var num7 = parseInt("0xf"); // 15(十六进制数)

注意,在使用 parseInt()解析像八进制字面量的字符串时, ECMAScript 3 和 5 存在分歧 ,所以,可以为这个函数提供第二个参数:转换时使用的基数(即多少进制)。如果知道要解析的值是十六进制格式的字符串,那么指定基数 16 作为第二个参数,可以保证得到正确的结果,例如:

var num = parseInt("0xAF", 16); //175

实际上,如果指定了 16 作为第二个参数,字符串可以不带前面的"0x",如下所示:

var num1 = parseInt("AF", 16); //175
var num2 = parseInt("AF"); //NaN

parseFloat

与 parseInt()函数类似, parseFloat()是从第一个非0非空字符开始解析每个字符。一直解析到字符串末尾,或者解析到遇见一个无效的浮点数字字符为止。也就是说,字符串中的第一个小数点是有效的,而第二个小数点就是无效的了,因此它后面的字符串将被忽略。举例来说,"22.34.5"将会被转换为 22.34。

parseFloat()可以识别前面讨论过的所有浮点数值格式,也包括十进制整数格式。但十六进制格式的字符串则始终会被转换成 0。由于 parseFloat()只解析十进制值,因此它没有用第二个参数指定基数的用法。最后还要注意一点:如果字符串包含的是一个可解析为整数的数(没有小数点,或者小数点后都是零), parseFloat()会返回整数。以下是使用 parseFloat()转换数值的几个典型示例。

var num1 = parseFloat("1234blue"); //1234 (整数)
var num2 = parseFloat("0xA"); //0
var num3 = parseFloat("22.5"); //22.5
var num4 = parseFloat("22.34.5"); //22.34
var num5 = parseFloat("0908.5"); //908.5
var num6 = parseFloat("3.125e7"); //31250000 

String

toString

要把一个值转换为一个字符串有两种方式。第一种是使用几乎每个值都有的 toString()方法

var age = 11;
var ageAsString = age.toString(); // 字符串"11"
var found = true;
var foundAsString = found.toString(); // 字符串"true"

数值、布尔值、对象和字符串值(没错,每个字符串也都有一个 toString()方法,该方法返回字符串的一个副本)都有 toString()方法。但 null 和 undefined 值没有这个方法。 多数情况下,调用 toString()方法不必传递参数。但是,在调用数值的 toString()方法时,可以传递一个参数:输出数值的基数。默认情况下, toString()方法以十进制格式返回数值的字符串表示。而通过传递基数, toString()可以输出以二进制、八进制、十六进制,乃至其他任意有效进制格式表示的字符串值。下面给出几个例子:

var num = 10;
alert(num.toString()); // "10"
alert(num.toString(2)); // "1010"
alert(num.toString(8)); // "12"
alert(num.toString(10)); // "10"
alert(num.toString(16)); // "a “

String()

在不知道要转换的值是不是 null 或 undefined 的情况下,还可以使用转型函数 String(),这个 函数能够将任何类型的值转换为字符串。

要把某个值转换为字符串,可以使用加号操作符(+)把它与一个字符 串("")加在一起。

++/--

var s1 = "2";
var s2 = "z";
var b = false;
var f = 1.1;
var o = {
valueOf: function() {
return -1;
}
};
s1++; // 值变成数值 3
s2++; // 值变成 NaN
b++; // 值变成数值 1
f--; // 值变成 0.10000000000000009(由于浮点舍入错误所致)
o--; // 值变成数值-2

+/-

+和numer()同规则

在将一元减操作符应用于数值时,该值会变成负数。而当应用于非数值时, 一元减操作符遵循与一元加操作符相同的规则,最后再将得到的数值转换为负数

位操作符

如果对非数值应用位操作符,会先使用 Number()函数将该值转换为一个数值(自动完成),然后 再应用位操作。得到的结果将是一个数值。

在 ECMAScript 中,当对数值应用位操作符时,后台会发生如下转换过程: 64 位的数值被转换成 32 位数值,然后执行位操作,最后再将 32 位的结果转换回 64 位数值。这样,表面上看起来就好像是在操 作 32 位数值,就跟在其他语言中以类似方式执行二进制操作一样。但这个转换过程也导致了一个严重 的副效应,即在对特殊的 NaN 和 Infinity 值应用位操作时,这两个值都会被当成 0 来处理。

按位非(NOT) ~

非操作的本质:操作数的负值减 1。

var num1 = 25; // 二进制 00000000000000000000000000011001
var num2 = ~num1; // 二进制 11111111111111111111111111100110
alert(num2); //

按位与(AND) &

按位与操作只在两个数值的对应位都是 1 时才返回 1,任何一位是 0,结果都是 0。

按位或(OR) |

按位或操作在有一个位是 1 的情况下就返回 1, 而只有在两个位都是 0 的情况下才返回 0。

按位异或(XOR) ^

这个操作在两个数值对应位上只有一个 1 时才返回 1,如果对 应的两位都是 1 或都是 0,则返回 0

左移 <<

这个操作符会将数值的所有位向左移动指定的位数。例如, 如果将数值 2(二进制码为 10)向左移动 5 位,结果就是 64(二进制码为 1000000), 注意,在向左移位后,原数值的右侧多出了 5 个空位。左移操作会以 0 来填充这些空位,以便得到 的结果是一个完整的 32 位二进制数

左移不会影响操作数的符号位。换句话说,如果将-2 向左移动 5 位,结果将是-64,而非 64。

有符号的右移 >>

这个操作符会将数值向右移动,但保留符号位(即 正负号标记)。有符号的右移操作与左移操作恰好相反,即如果将 64 向右移动 5 位,结果将变回 2:

同样,在移位过程中,原数值中也会出现空位。只不过这次的空位出现在原数值的左侧、符号位的 右侧(见图 3-3)。而此时 ECMAScript 会用符号位的值来填充所有空位,以便得到一个完整的值。

无符号右移 >>>

无符号右移操作符由 3 个大于号(>>>)表示,这个操作符会将数值的所有 32 位都向右移动。对正 数来说,无符号右移的结果与有符号右移相同。

但是对负数来说,情况就不一样了。首先,无符号右移是以 0 来填充空位,而不是像有符号右移那 样以符号位的值来填充空位。所以,对正数的无符号右移与有符号右移结果相同,但对负数的结果就不一样了。其次,无符号右移操作符会把负数的二进制码当成正数的二进制码。而且,由于负数以其绝对 值的二进制补码形式表示,因此就会导致无符号右移后的结果非常之大,

布尔操作符

非(NOT)!

逻辑非操作符首先会将它的操作数转换为一个布尔值与Boolean()规则相同,然后再对其求反。

与(AND)&&

逻辑与操作可以应用于任何类型的操作数,而不仅仅是布尔值。在有一个操作数不是布尔值的情况 下,逻辑与操作就不一定返回布尔值;此时,它遵循下列规则:

逻辑与操作属于短路操作,即如果第一个操作数能够决定结果,那么就不会再对第二个操作数求值。 对于逻辑与操作而言,如果第一个操作数是 false,则无论第二个操作数是什么值,结果都不再可能是 true 了。

或(OR)||

逻辑或操作符也是短路操作符

乘性操作符

乘 *

除法 /

求模 %

加性操作符

加法 +

如果有一个操作数是对象、数值或布尔值,则调用它们的 toString()方法取得相应的字符串值, 然后再应用前面关于字符串的规则。对于 undefined 和 null,则分别调用 String()函数并取得字符 串"undefined"和"null"。

减法 -

关系操作符

相等操作符