ECMAScript 有 6 种简单数据类型(也称为原始类型):Undefined、Null、Boolean、Number、 String 和 Symbol。还有一种复杂数据类型叫 Object(对 象)。Object 是一种无序名值对的集合。
Undefined 和 NullUndefined 类型只有一个值 undefined,当使用 let 或 var 声明变量单并没有初始化时,就相当于给变量赋予了 undefined 值。
一般来说不建议显式的给变量赋值 undefined,字面值 undefined 主要是用来比较。
1 2 3 4 5 let v1;var v2;console .log(v1); console .log(v2); console .log(v1 === v2);
增加这个特殊值的目的就是为了正式明确空对象指针 null 和未初始化变量的区别。
undefined 值是由 null 值派生而来的,因此 ECMA-262 将它们定义为表面上相等,如下所示:
1 2 console .log(null === undefined ); console .log(null == undefined );
Null 类型同样只有一个值,即特殊值 null。逻辑上讲,null 值表示一个空对象指针,这也是给 typeof 传一个 null 会返回 “object” 的原因。
1 2 let v3 = null ;console .log(typeof v3);
在定义将来要保存对象值的变量时,建议使用 null 来初始化,不要使用其他值。这样,只要检查这个变量的值是不是 null 就可以知道这个变量是否在后来被重新赋予了一个对象的引用。
undefined 和 null 都是假值,如果只是为了检测假值,可以方便的检测它们;如果是明确的想要检测 undefined 或 null,则需要显式的对其进行判断。
1 2 3 4 5 6 let v4;let o1 = null ;console .log(!v4); console .log(v4 === undefined ); console .log(!o1); console .log(o1 === null );
BooleanBoolean 类型是使用非常频繁的数据类型,它有两个值 true 和 false (布尔值字面量是区分大小写的)。
这两个布尔值并不等同于数值:
1 2 3 4 let t1 = true ;let f1 = false ;console .log(t1 === 1 ); console .log(f1 === 0 );
虽然布尔值只有两个,但所有其他 ECMAScript 类型的值都有相应布尔值的等价形式。要将一个其他类型的值转换为布尔值,可以调用特定的 Boolean() 转型函数。
1 2 3 4 5 6 7 8 9 10 11 console .log(Boolean (true )); console .log(Boolean (false )); console .log(Boolean ('true' )); console .log(Boolean ('false' )); console .log(Boolean (0 )); console .log(Boolean (-0 )); console .log(Boolean (NaN )); console .log(Boolean (1 )); console .log(Boolean (-1 )); console .log(Boolean ('' )); console .log(Boolean (' ' ));
NumberNumber 类型使用 IEEE 754 格式表示整 数和浮点值(在某些语言中也叫双精度值)。不同的数值类型相应地也有不同的数值字面量格式。
整数可以用八进制、十进制和十六进制字面量表示,但是使用八进制和十六进制格式创建的数值在所有数学操作中都被视为十进制数值。
1 2 3 4 5 6 let octalNum = 077 ;let hexNum = 0xff ;console .log(octalNum); console .log(hexNum); let sum = octalNum + hexNum;console .log(sum);
浮点值 要定义浮点值,数值中必须包含小数点,而且小数点后面必须至少有一个数字。虽然小数点前面不是必须有整数,但推荐加上。
1 2 let float1 = 1.01 ;let float2 = .01 ;
因为存储浮点值使用的内存空间是存储整数值的两倍,所以 ECMAScript 总是想方设法把值转换为 整数。在小数点后面没有数字的情况下,数值就会变成整数。类似地,如果数值本身就是整数,只是小 数点后面跟着 0(如 1.0),那它也会被转换为整数。
对于非常大或非常小的数值,浮点值可以用科学记数法来表示。科学记数法用于表示一个应该乘以 10 的给定次幂的数值。ECMAScript 中科学记数法的格式要求是一个数值(整数或浮点数)后跟一个大 写或小写的字母 e,再加上一个要乘的 10 的多少次幂
1 2 3 4 let float3 = 2.23e9 ;console .log(float3); let float4 = 1.01e-5 ;console .log(float4);
浮点值的精确度最高可达 17 位小数 ,但在算术计算中远不如整数精确。例如,0.1 加 0.2 得到的不 是 0.3,而是 0.300 000 000 000 000 04。由于这种微小的舍入错误,导致很难测试特定的浮点值。
1 2 3 let float5 = 0.1 ;let float6 = 0.2 ;console .log(float5 + float6);
之所以存在这种舍入错误,是因为使用了 IEEE 754 数值,这种错误并非 ECMAScript 所独有。其他使用相同格式的语言也有这个问题。
因此永远不要测试某个特定的浮点值。
使用最小精度值来比较浮点数:
1 console .log( Math .abs(0.1 + 0.2 - 0.3 ) <= Number .EPSILON);
值的范围 ECMAScript 可以表示的最小 数值保存在 Number.MIN_VALUE 中,这个值在多数浏览器中是 5e-324;可以表示的最大数值保存在 Number.MAX_VALUE 中,这个值在多数浏览器中是 1.7976931348623157e+308。如果某个计算得到的数值结果超出了 JavaScript 可以表示的范围,那么这个数值会被自动转换为一个特殊的 Infinity(无 穷)值。任何无法表示的负数以 -Infinity(负无穷大)表示,任何无法表示的正数以 Infinity(正 无穷大)表示。
1 2 console .log(Number .MIN_VALUE); console .log(Number .MAX_VALUE);
如果计算返回正 Infinity 或负 Infinity , 则该值将不能再进一步用于任何计算。 这是因为 Infinity 没有可用于计算的数值表示形式。要确定一个值是不是有限大(即介于 JavaScript 能表示的最小值和最大值之间),可以使用 isFinite() 函数。
1 2 3 4 let num1 = 6e-325 ;let num2 = 1.8e308 ;console .log(Number .isFinite(num1)); console .log(Number .isFinite(num2));
Number.NEGATIVE_INFINITY 和 Number.POSITIVE_INFINITY 也可以获取正、负 Infinity。没错,这两个属性包含的值分别就是 -Infinity 和 Infinity。
NaN有一个特殊的数值叫 NaN,意思是 “不是数值”(Not a Number),用于表示本来要返回数值的操作 失败了(而不是抛出错误)。比如,用 0 除任意数值在其他语言中通常都会导致错误,从而中止代码执 行。但在 ECMAScript 中,0、+0 或-0 相除会返回 NaN。
1 2 3 4 console .log(Number .parseFloat('f1.f' )); console .log(1 /0 ); console .log(0 /1 ); console .log(0 /0 );
NaN 有几个独特的属性。首先,任何涉及 NaN 的操作始终返回 NaN(如 NaN/10),在连续多步计算 时这可能是个问题。其次,NaN 不等于包括 NaN 在内的任何值。
1 2 console .log(0 /0 === NaN ); console .log(NaN === NaN );
要判断一个值是不是 NaN, 可以使用 isNaN() 函数。
1 2 console .log(Number .isNaN(0 /0 )); console .log(Number .isNaN(true ));
数值转换 JavaScript 中提供了 Number(),parseInt(),parseFloat() 三个方法用来将非数值转换为数值。
Number1 2 3 4 5 6 7 8 console .log(Number (true )); console .log(Number (false )); console .log(Number (1000 )); console .log(Number (null )); console .log(Number (undefined )); console .log(Number ('12' )); console .log(Number (' 12' )); console .log(Number ('12-' ));
parseInt()parseInt() 函数更专注于字符串是否包含数值模式。字符串最前面的空格会被忽略,从第一个非空格字符开始转换。如果第一个字符不是数值字符、加号或减号,parseInt() 立即 返回 NaN。这意味着空字符串也会返回 NaN(这一点跟 Number() 不一样,它返回 0)。如果第一个字符 是数值字符、加号或减号,则继续依次检测每个字符,直到字符串末尾,或碰到非数值字符。
1 2 3 4 5 6 console .log(parseInt (100 )); console .log(parseInt ('1000' )); console .log(parseInt ('1000lll' )); console .log(parseInt (' 1000' )); console .log(parseInt ('001000' )); console .log(parseInt ('a 1000' ));
parseInt() 也接收第二个参数,用于指定底数(进制数)。
1 2 console .log(parseInt ('077' , 8 )); console .log(parseInt ('0xff' , 16 ));
不传底数参数相当于让 parseInt() 自己决定如何解析,所以为避免解析出错,建议始终传给 它第二个参数。
parseFloat()parseFloat() 函数的工作方式跟 parseInt() 函数类似,都是从位置 0 开始检测每个字符。同样, 它也是解析到字符串末尾或者解析到一个无效的浮点数值字符为止。这意味着第一次出现的小数点是有效的,但第二次出现的小数点就无效了,此时字符串的剩余字符都会被忽略。
1 2 3 4 5 6 7 console .log(parseFloat ('-1.01' )); console .log(parseFloat ('1.01' )); console .log(parseFloat ('1.01.01' )); console .log(parseFloat (' 1.01' )); console .log(parseFloat ('a1.01' )); console .log(parseFloat ('1.01a' )); console .log(parseFloat ('00001.01a' ));
StringString(字符串)数据类型表示零或多个 16 位 Unicode 字符序列。
ECMAScript 中的字符串是不可变的(immutable),意思是一旦创建,它们的值就不能变了。要修改某个变量中的字符串值,必须先销毁原始的字符串,然后将包含新值的另一个字符串保存到该变量。
把值转换为字符串 使用 toString() 方法 null 和 undefined 没有 toString() 方法。
1 2 3 4 5 6 7 8 9 10 11 12 let val1 = 12 ;let val2= '12' ;let val3 = [1 ,2 ];let val4 = new Date ();let val5 = {};console .log(val1.toString(), val2.toString(), val3.toString(), val4.toString(), val5.toString());null .toString(); undefined .toString();
在对数字类型值调用 toString() 方法时,可传递一个参数指定以什么底数输出数值的字符串表示。
1 2 3 4 5 6 let numVal = 123 ;console .log(numVal.toString(2 )); console .log(numVal.toString(8 )); console .log(numVal.toString(10 )); console .log(numVal.toString(16 ));
使用 String() 在使用 String() 将值转换为字符串时,如果值有 toString() 方法,则直接调用 toString() 方法并返回结果。对于没有 toString() 方法的 null 和 undefined ,则会分别返回 “null” 和 “undefiend”。
1 2 console .log(String (null ));console .log(String (undefined ));
SymbolSymbol(符号)是 ECMAScript 6 新增的数据类型。符号是原始值,且符号实例是唯一 、不可变 的。 符号的用途是确保对象属性使用唯一标识符,不会发生属性冲突的危险。
尽管听起来跟私有属性有点类似,但符号并不是为了提供私有属性的行为才增加的。相反,符号就是用来创建唯一记号,进而用作非字符串形式的对象属性。
1 2 3 4 let s1 = Symbol ();let s2 = Symbol ('s2' );console .log(s1);console .log(s2);
ObjectECMAScript 中的对象其实就是一组数据和功能的集合。对象通过 new 操作符后跟对象类型的名称 来创建。