1、七种数据类型

1.1 null
- 基本类型中唯一一个假值
- null是空值,指曾经赋值过,但是目前没有值
- 是一个特殊关键字,不是标识符,我们不能将其当作变量来使用和赋值
1.2 undefined
- 没有值,从未赋值
- 是一个标识符,可以当做变量使用和赋值
2 其他
2.1 typeof
数据类型 | typeof |
---|---|
null | "object"(是语言的bug) |
number | "number" |
boolean | "boolean" |
string | "string" |
boolean | "boolean" |
object | "object" |
Symbol | "symbol" |
undeclared | "undefined" |
NaN | "number" |
2.2 undeclared
报 错:ReferenceError: a is not defined
2.3 NaN
- 是 JavaScript 中唯一一个不等于自身的值。
- isNaN(..) 有一个严重的缺陷,“检查参数是否不是NaN,也不是数字”,输入字符串返回true
- ES6 Number.isNaN(..)
3总结
3.1 数据类型总结
- JavaScript 中的变量是没有类型的,只有值才有。变量可以随时持有任何类型的值。
- JavaScript 不做“类型强制” --- JS不是强类型语言
- 在对变量执行 typeof操作时,得到的结果并不是该变量的类型,而是该变量持有的值的类 型,因为 JavaScript 中的变量没有类型。
- undefined(声明但还没有赋值的变量)不同于 undeclared(未声明)。 变量未声明,是undeclared;对象属性不存在,是undefined
3.2 数组
- 在 JavaScript 中,数组可以容纳任何类型的值
- delete删除数组元素,length 属性不会变化
- 稀疏”数组(sparse array):含有空白或空缺单元的数组\
- 数组通过数字进行索引,也可以包含字符串键值和属性,但是不计算在数组长度内
- 如果字符串键值能够被强制类型转换为十进制数字的话,它就会被当作数字索引来处理。
- 类数组 用slice转换成数组 var arr = Array.prototype.slice.call( arguments );
- arguments 对象从 ES6 开始已废止
3.3 字符串
- 字符串经常被当成字符数组,但实际上字符串和字符数组并不是一回事
- 字符是类数组,有length 属性以及 indexOf(..)(从 ES5开始数组支持此方法)和concat(..) 方法
- JavaScript 中字符串是不可变的,而数组是可变的。所以str[0]='a' 赋值失败,正确的方法应该是 a.charAt(1)。
- 字符串不可变是指字符串的成员函数不会改变其原始值,而是创建并返回一个新的字符串。而数组的成员函数都是在其原始值上进行操作。
- 数组有一个字符串没有的反转函数 reverse():
3.4 数字
- JavaScript 只有一种数值类型:number(数字),包括“整数”和带小数的十进制数,“整数”之所以加引号是因为JavaScript 没有真正意义上的整数
- JavaScript 中的“整数”就是没有小数的十进制数。所以 42.0 即等同于“整数”42。
- JavaScript 使用的是“双精 度”格式(即 64 位二进制)。
- 数字前面的 0 可以省略 .42
- 小数点后小数部分最后面的 0 也可以省略 42.
- log时小数部分最后面的 0 被省略 a=43.30000 输出a为43.3
- 指数
var a = 5E10;
a; // 50000000000
a.toExponential(); // "5e+10" -- 有引号
- tofixed(..) 方法可指定小数部分的显示位数 输出结果实际上是字符串
- toPrecision(..)方法用来指定有效数位的显示位数(加上整数,不加指数,输出字符串)
- 数字常量也可以调用Number对象的方法,但是要多加一个.
// 无效语法:
42.toFixed( 3 ); // SyntaxError
// 下面的语法都有效:
(42).toFixed( 3 ); // "42.000"
0.42.toFixed( 3 ); // "0.420"
42..toFixed( 3 ); // "42.000"
42 .toFixed(3); // "42.000"
3.5各种进制
- 八进制 OO Oo 十六进制 OX Ox 二进制 OB Ob
- 浮点数 0.1 + 0.2 === 0.3; // false
- 3、设置一个误差范围值,叫机器精度(machine epsilon),JS中这个值通常是 2^-52 (2.220446049250313e-16)。
- ES6,Number.EPSILON Math.abs( n1 - n2 ) < Number.EPSILON
- 最大浮点数 Number. MAX_VALUE 中。最小浮点数定义在 Number.MIN_VALUE 中,它不是负数,但 无限接近于 0 !
- 能够被“安全”呈现的最大整数是2^53 - 1,在ES6中被定义为 Number.MAX_SAFE_INTEGER。
- 最 小 整 数 是 -9007199254740991, 在 ES6 中 被 定 义 为 Number. MIN_SAFE_INTEGER。
- JavaScript 的数字类型无法精确呈现 64位数值,所以必须将它们保存(转换)为字符串。
- 检测一个值是否是整数,可以使用 ES6 中的 Number.isInteger(..) 方法
- 检测一个值是否是安全的整数,可以使用 ES6 中的 Number.isSafeInteger(..) 方法
- 数位运算符|只适用于32位 整数
3.6特殊数值
- 通过 void 运算符即可得到undefined,比如 void a
- void并不改变表达式的结果, 只是让表达式不返回值
- 无穷
1 / 0; Number.POSITIVE_INfiNITY
-1 / 0; Number.NEGATIVE_ INfiNITY
Infinity/ Infinity = NaN
有穷正数 / Infinity = 0
- 计算结果一旦溢出为无穷数(infinity)就无法再得到有穷数。可以从有 穷走向无穷,但无法从无穷回到有穷。
3.7 负零 -0
- 加法和减法运算不会得到负零
- 0和负数的乘除操作会返回-0
- JSON.stringify(-0) 返回 "0",而 JSON.parse("-0") 返回 -0。
- -0 == 0; // true
- 1 / -0 = Number.NEGATIVE_ INfiNITY
- 判断负零 isNegZero(..)
- ES6 中新加入了一个工具方法 Object.is(..) 来判断两个值是否绝对相等,Object.is( -3 * 0, -0 ); //true 能使用 == 和 ===时就尽量不要使用 Object.is(..),因为前者效率更高,Object.is(..) 主要用来处理那些特殊的相等比较。
3.8 值和引用
- JavaScript 中没有指针,变量不可能成为指向另一个变量的引用。JavaScript 引用指向的是值。
- JavaScript 对值和引用的赋值传递在语法上没有区别,完全根据值的类型来决定
- 简单值(即标量基本类型值)总是通过值复制的方式来赋值 / 传递
- 复合值——对象,总是通过引用复制的方式来赋值 / 传递。
- 由于引用指向的是值本身而非变量,所以一个引用无法更改另一个引用的指向。
理解以下代码:
var c = [1,2,3];
var d = c; // d是[1,2,3]的一个引用 d.push( 4 );
c; // [1,2,3,4]
d; // [1,2,3,4]
var a = [1,2,3];
var b = a;
a; // [1,2,3]
b; // [1,2,3]
// 然后
b = [4,5,6];
a; // [1,2,3]
b; // [4,5,6]
//我们不能通过引用 x 来更改引用 a 的指向,只能更改 a 和 x 共同指向的值。
function foo(x) {
x.push( 4 );
x; // [1,2,3,4]
// 然后
x = [4,5,6];
x.push( 7 );
x; // [4,5,6,7]
}
var a = [1,2,3];
foo( a );
a; // 是[1,2,3,4],不是[4,5,6,7]
//要将 a 的值变为 [4,5,6,7],必须更改 x 指向的数组,而不是为 x 赋值一个新的数组。
function foo(x) {
x.push( 4 );
x; // [1,2,3,4]
// 然后
x.length = 0; // 清空数组 x.push( 4, 5, 6, 7 );
x; // [4,5,6,7]
}
var a = [1,2,3];
foo( a );
a; // 是[4,5,6,7],不是[1,2,3,4]
- 想通过值复制的方式来传递复合值(如数组),就需要为其创建一个复本,这样传递的 就不再是原始值。例如foo( a.slice() );
- 要将标量基本类型值传递到函数内并进行更改,就需要将该值封装到一个复合值(对象、数组等)中,然后通过引用复制的方式传递。
function foo(x) {
x = x + 1;
x; // 3 }
var a = 2;
var b = new Number( a ); // Object(a)也一样
foo( b );
console.log( b ); // 是2,不是3
标量基本类型值是不可更改的(字符串和布尔也是如此)。
如果一个数字对象的标量基本类型值是2,那么该值就不能更改,除非创建一个包含新值的数字对象。
x = x + 1中,x中的标量基本类型值2从数字对象中拆封(或者提取)出来后,
x就神不知鬼不觉地从引用变成了数字对象,它的值为2 + 1等于3。然而函数外的b仍然指向原来那个值为 2 的数字对象。
- 基本类型的值是不可变的
var str = "123hello321";
str.toUpperCase(); // 123HELLO321
console.log(str); // 123hello321
- 基本类型的比较是它们的值的比较
var a = 1;
var b = true;
console.log(a == b); // true
console.log(a === b); // false
- 引用类型的比较是引用的比较
var obj1 = {}; // 新建一个空对象 obj1
var obj2 = {}; // 新建一个空对象 obj2
console.log(obj1 == obj2); // false
console.log(obj1 === obj2); // false
相关资料
《你不知道的JS中卷》