0. 前言
这篇文章是《你所不知道的JavaScript》读书笔记系列的第六篇文章。在这篇文章中,我们来聊一聊JavaScript的类型和值。
- 《你所不知道的JavaScript》读书笔记(一):作用域和闭包(上)
- 《你所不知道的JavaScript》读书笔记(一):作用域和闭包(下)
- 《你所不知道的JavaScript》读书笔记(二):this指向问题
- 《你所不知道的JavaScript》读书笔记(三):对象和类(上)
- 《你所不知道的JavaScript》读书笔记(三):对象和类(下)
1. JavaScript 类型
相信任何一个有js开发经验的小伙伴,都知道JavaScript中有七种内置类型:
- 空值(null)
- 未定义(undefind)
- 布尔值(boolean)
- 数字(number)
- 字符串(string)
- 对象(object)
- 符号(symbol) 关于JavaScript的类型,有以下几点需要注意的:
- 可以用
typeof
运算符来查看值得类型 - 除了
null
之外,用typeof
运算符检测类型的结果均有同名的字符串与之对应,即:typeof undefined === "undefined"
typeof true === "boolean"
typeof 42 === "number"
typeof "42" === "string"
typeof { life: 42 } === "object"
typeof Symbol() === "symbol"
null
的typeof
运算结果是"object"
, 即typeof null === "object"
null
是基本类型中唯一一个"假值"- function也是JavaScript的一个内置类型,它是object的一个字类型。具体来说,函数可调用对象,他有一个内部属性
[[call]]
,该属性使其可以被调用。 - 数组也是对象,用
typeof
来检测数组的类型,得到的返回值是object
。这里需要注意返回值不是"array"
- JavaScript中的变量是没有类型的,只有值才有
undefined
和undeclared
的问题:- 变量在未持有值得时候为
undefined
。此时,typeof
返回"undefined"
- 还没有在作用域中声明过的变量,是
undeclared
的。当我们使用一个未在作用域中声明过的变量时,会报错RefrenceError: xxx is not defined
, 而且当我们使用typeof
一个未声明的变量时,得到的结果是"undefined"
- 变量在未持有值得时候为
2. JavaScript值
和很多编程语言一样,JavaScript也有几种基本的内置值类型:数组(array)、字符串(string)、数字(number)以及表示真(true)/假(false)的布尔值。除此之外,JavaScript还有两个特殊的伙伴:null 和 undefined。
2.1 数组
- 在JavaScript中,数组可以容纳任何类型的值,可以是字符串、数字、对象,甚至是其他数组
- 对数组声明后可向其中加入之,不需要预先设定大小
- 数组一般通过数字来进行索引,但也可以通过属性来索引,但是这些索引并不计算在数组长度内(但是最好不要在数组中加入字符串键值/属性,就正常用就可以了)
- 字符串的键值能够被强制类型转换为十进制的话,它会被当作数字索引来处理
- 数组的创建方法:
var a = []
var a = new Array(10)
2.2 字符串
- JavaScript中的字符串和字符数组并不是一回事,最多只是看上去相似而已
- JavaScript中字符串是不可变的,而数组是可变的
2.3 数字
- JavaScript中只有一种数值类型,即number(数字),包括“整数”和带下属的十进制数
- JavaScript中没有真正意义上的整数,他所说的整数就是没有小鼠的十进制数
- 特别大和特别小的数组默认用指数格式显示,例如
var a = 5E10
toExponential()
可以将数字转化成指数形式toFixed()
可以指定小数部分的显示位数.
运算符会被优先识别为数字常量的一部分:42.toFixed(3) // 无效语法,会报错:SyntaxError // 下面的语法都有效 (42).toFixed(3) // "42.000" 0.42.toFixed(3) // "0.420" 42..toFixed(3) // "42.000"
- 数字常量还可以使用其他进制:
0xf3 // 243的十六进制 0363 // 243的八进制
- 经典面试问题:
0.1 + 0.2 === 0.3
:从数学角度来说,上面的条件判断应该是true,但是你打开浏览器的console,把他输进去,得到的结果却是false,原因如下:二进制浮点数中的0.1和0.2并不是十分精确,它们相加的结果并非刚好等于0.3,而是一个比较接近的数字0.30000000000000004,所以条件判断结果为false - “整数”的安全值范围远远小于
Number.MAX_VALUE
,能够被安全呈现的最大整数是2^53-1
,即9007199254740991;最小整数是-9007199254740991,在ES6中被定义为Number.MIN_SAFE_INTEGER
- 检测一个数是否为整数可以采用
Number.isInteger()
方法;检测一个数是否为安全的整数,可以使用Number.isSafeInteger()
方法。 NaN
相关:- NaN意指“不是一个数字”,可以将它理解为“无效数值”、“失败数值”或者“坏数值”
- NaN仍然是数字类型,用
typeof
的检测结果是"number"
- NaN用来指出数字类型中的错误情况,即执行数学运算没有成功,这是失败后返回的结果
- NaNcy是唯一一个非自反(即
x === x
不成立)的值。而NaN != NaN为true
- 无穷数:
- 在JavaScript中,无穷数用
Infinity
表示 - 计算结果一旦溢出为无穷数,就无法在得到有穷数
Infinity / Infinity
的结果是NaN1/0 === Inifinity
,-1/0 === -Infinity
- 在JavaScript中,无穷数用
- 零值:
- 有些应用程序中的数据需要以级数形式来表示(比如动画帧的移动速度),数字的符号位用来代表其他信息(比如移动的方向)。此时如果一个值为0的变量失去了它的符号位,它的方向信息就会丢失。所以保留0值的符号位可以防止这类情况发生。
2.4 特殊的值
- null:指空值,表示曾赋过值,但目前没有值
- undefined:指没有值,表示从未赋值
2.5 值的引用问题
- 简单值(即标量基本类型值)总是通过值复制的方式来进行赋值,包括null、undefined、字符串、数字、布尔和ES6中的symbol
- 复合值——对象(包括数组和封装对象)和函数,则总是通过引用复制的方式来赋值。这里需要特别注意的是,传递引用的方式进行赋值的情况,用
===
来判断是否相等时,总是得到false的