JS 数据类型 (01) - 有哪些?有什么区别 ?

120 阅读9分钟

JS 数据类型分为基本数据类型、复杂数据类型(也叫做引用数据类型)

JS 基本数据类型

Undefined

定义

Undefined 类型只有一个值,就是特殊值 undefined. 当使用 var 或者 let 声明了变量但是没有初始化时,相当于给变量赋予了 undefined 值

let message 
console.log(message  == undefined) // true
console.log(typeof message) // undefined
// 注意:对于一个未声明的变量使用 typeof 类型检测,值也是 undefined
console.log(typeof age) // undefined

注意:

  • 对于一个未声明的变量使用 typeof 类型检测,值也是 undefined(例子看上面代码)
  • 虽然未初始化的变量会自动赋予 undefined 值,但是仍然建议在声明变量的同时进行初始化。
    • 这样我们使用 typeof 检测类型得到 undefined 时,就可以知道是声明了但是未初始化,还是未声明

Null

定义

Null 类型同样只有一个值,即特殊值 null. 逻辑上讲,null 的值表示一个空对象指针。

注意

  • 在定义将来要保存对象值的变量时,建议使用 null 来进行初始化,不要使用其他值

  • null 是 由 undefined 值派生而来的

    console.log(null == undefined) // true
    
  • null 和 undefined 有关系,但是用途却不一样

    • 对于 undefined,我们永远不需要显式地将变量值设置为 undefined
    • 对于变量,只要保存对象,而当时又没有那个对象可以保存,可以先用 null 类进行填充。(这样就可以保持 null 是空指针的语音,也进一步与 undefind 进行区分)
  • 使用 typeof 检测 null 类型时返回 object

    console.log(typeof null) // "object"
    

Number

定义

ECMAScript 中最有意思的数据类型。Number 类型使用 IEEE 754 格式表示整点数和浮点数(在某些语言中也叫做双精度)

数值字面格式

  • 十进制(最基本的数值字面量格式)
  • 八进制
    • 第一个数字必须是0,然后后面是相应的八进制数字0-7
    • 八进制在严格模式下是无效的,会导致 JavaScript 引擎抛出语法错误
  • 十六进制
    • 前缀必须是 0x(区分大小写),然后是十六进制数字(0-9以及A-F)
    • 十六进制数字钟的字母大小写均可
    let hexNum1 = 0xA;  // 十六进制 10
    let hexNum2 = 0x1f; // 十六进制 31
    

浮点数

  • 要定义浮点数,数值中必须包含小数点,并且小数点后面必须至少有一位数字。
  • 因为存储浮点数使用的存储空间是存储整数值的两倍,所以ECMAScript 总是想方设法把值转换为整数。小数点后面没有数字情况下,数值就会变为整数。
  • 对于非常大或者非常小的数值,浮点数可以使用科学计数法来表示。
    • 默认情况下,ECMAScript 会将小数点后至少包含6个零的浮点值转换为科学计数法
    0.000 0003 => 3e-7
    
  • 浮点数的精度最高可达17位,但是在算术运算中远不如整数精度

  • 0.1 + 0.2 = 0.30000000000000004

    let a = 0.1
    let b = 0.2
    if(a + b === 0.3){
            // 千万别这么干
    }
    

值的范围

  • ECMAScript 可以表示的最小数值保存在 Number.MIN_VALUE 中,这个值在大多数浏览器中是 5e-324
  • 可以表示的最大值保存在 Number.MAX_VALUE 中,这个值在多数浏览器中是 1.797 693 134 862 3156 7e+308
  • 超出最大值, 这个值会自动转换为一个特殊的Infinity无穷值
  • 任何无法表示的负数以 -Infinity负无穷大表示,任何无法表示的整数以Infinity表示
  • 可以使用isFinite函数来判断一个数值是不是有限大(即介于JavaScript 能表示的最大值和最小值之间)

NaN

特殊值 NaN: Not a Number,不是一个数值。用于表示本来要返回数值的操作失败了(而不是抛出错误)

console.log(0/0) // NaN
console.log(-0/0) // NaN
  • 任何涉及 NaN 的操作始终返回 NaN ( 如 NaN + 10)
  • NaN 不等于包含 NaN在内的任何值
  • isNaN 函数:接受一个参数,可以是任意数据类型,然后判断这个参数是否“不是数值”
    • 任何不能转换为数值的值都会导致这个函数返回 true

数值转换

  • parseInt()
    • 字符串前面的空格会被忽略,从第一个非空格字符开始转换
    • 会依次检测每个字符,直到字符串结尾,或者碰到非数值字符
    • 第二个参数可以指定底数(进制数),不传底数就相当于让 parseInt 自己决定如何解析,所以为了避免解析错误,建议始终传递第二个参数
  • parseFloat()
    • 解析处理方式和 parseInt 类似,都是从位置0开始检测字符,直到字符末尾或者解析到一个无效的浮点数值字符为止
    • 另一个不同在于,它会忽略字符串开头的零
    • 它只能解析十进制数值,不能指定底数
  • Number()

image.png

注意

  • 正零(+0)和 负零(-0)在所有情况下都被认为是等同的

  • 0.1 + 0.2 !== 0.3

  • 任何涉及 NaN 的操作始终返回 NaN ( 如 NaN + 10)

  • NaN 不等于包含 NaN在内的任何值

    console.log(NaN  == NaN)  //false
    
  • 使用 parseInt 时,建议添加第二个参数,指定解析进制数

  • 使用 parseFloat 只能解析十进制,不能指定底数

String

定义

用来表示零或者多个 16位 Unicode 字符序列。可用单引号、双引号、反引号来标示

特点

  • ECMAScript 中的字符串是不可变的
    • 一旦创建,他们的值就不能变了
    • 要修改某个变量中的字符串,就必须先销毁原始字符串,然后将一个新的字符串保存到变量中

转换为字符串

  • 几乎所有值都有对应的 toString() 方法:这个方法唯一的作用就是返回当前值的字符串等价物
    • null 和 undefined 没有 toString 方法
    • toString() 接受一个底数参数,默认是 十进制底数
  • String() 方式转换

Boolean

定义

布尔值是 ECMAScript 中使用最频繁的类型之一,有两个字面量:true 和 false

注意

  • 布尔值字面量 true 和 false 是区分大小写的
    • True 和 False 是有效的标识符,但不是布尔值

转换规则

数据类型转换为 true 的值转换为 false 的值
Booleantruefalse
String非空字符串空字符串""(包含换行符\r\n等)
Number非零数值(包括无穷大)0、NaN
Object任意对象null
UndefinedN/A(不存在)undefined

Symbol(ES6 新增数据类型)

基本定义

Symbol 本质上是一种唯一标识符,可用作对象的唯一属性名,这样其他人就不会改写或覆盖你设置的属性值。

特点:

唯一性

即使是用同一个变量生成的值也不相等。

 let id1 = Symbol('id');
 let id2 = Symbol('id');
 console.log(id1 == id2);  //false
不可遍历性
  • for···in,object.keys() 不能访问
let id = Symbol("id");
let obj = {
    [id]: 'symbol'
};
for (let option in obj) {
    console.log(obj[option]); //空
}
  • 可以通过 Object.getOwnPropertySymbols 方法来进行获取遍历
let id1 = Symbol("id1");
let id2 = Symbol("id2");
let obj = {
  wid: 111,
  [id1]: 'aaa',
  [id2]: 'bbb'
};
let array = Object.getOwnPropertySymbols(obj);
console.log(array); // [ Symbol(id1), Symbol(id2) ]
console.log(obj[array[0]]);  // aaa

其他 API

Symbol.for()

也时候我们需要多次使用同一个symbol值的情况,就可使用这个方法

通过这种方法就可以通过参数值获取到全局的symbol对象;

let name1 = Symbol.for('name'); //检测到未创建后新建
let name2 = Symbol.for('name'); //检测到已创建后返回
console.log(name1 === name2); // true
Symbol.keyFor()

通过symbol对象获取到参数,使用Symbol.keyFor()

let name1 = Symbol.for('name');
let name2 = Symbol.for('name');
console.log(Symbol.keyFor(name1));  // 'name'
console.log(Symbol.keyFor(name2)); // 'name'

BigInt(ES6 新增数据类型)

基本定义

BigInt 是一种特殊的数字类型,它提供了对任意长度整数的支持。
创建 bigint 的方式有两种:在一个整数字面量后面加 n 或者调用 BigInt 函数。

console.log(90099999999999992 === 90099999999999993); // true
console.log(90099999999999992n === 90099999999999993n); // false
console.log(BigInt("90099999999999992") === BigInt("90099999999999993")); // false

相关文章

bigInt 解决了什么问题,适用于那些场景?

markdowner.net/article/228…

复杂数据类型

Object

目前为止,大多数引用值的示例使用的是 Object 类型。Object 是 ECMAScript 中最常用的类型之一。虽然 Object 的实例没有多少功能,但是很适合存储和在应用程序间交换数据。

显示的创建Object 有两种方式

  • 使用 new 操作符和 Object 构造函数

    function myNew(Con, ...args) {
      // 创建一个新的空对象
      let obj = {};
      // 将这个空对象的__proto__指向构造函数的原型
      // obj.__proto__ = Con.prototype;
      Object.setPrototypeOf(obj, Con.prototype);
      // 将this指向空对象
      let res = Con.apply(obj, args);
      // 对构造函数返回值做判断,然后返回对应的值
      return res instanceof Object ? res : obj;
    }
    
  • 使用对象字面量表示

Array

创建方式

  • 使用 Array 构造函数
  • 使用数组字面量

检测数组

  • instanceof
    • 使用 instanceof 的问题是是假定只有一个全局执行上下文。如果页面中有多个框架(比如 iframe),则可能涉及两个不同的全局执行上下文,因此就会有两个不同版本的 Array 构造函数。
  • Array.isArray
    • 这个方法用来确定一个值是否是数组,而不用管它是在哪个全局执行上下文中创建的

相关API

迭代器方法
  • keys()
  • values()
  • entries()
复制和填充方法
  • fill()
  • copyWith()
转换方法
  • toLocalString()
  • toString()
  • valueOf()
栈方法
  • push()
  • pop()
队列方法
  • shift(): 删除数组第一项并返回它,数组长度减1
  • unshfit():向数组开头添加任意多个值,并返回新的数组长度。
排序方法
  • reverse()
  • sort()
操作方法
  • concat()
  • slice()
  • splice()
搜索和位置方法
严格相等
  • indexOf()
  • lastIndexOf()
  • includes()
断言函数

允许按照定义的断言函数搜索数组,每个索引都会调用这个函数

  • find()
  • findIndex()
迭代方法
  • every()
  • filter()
  • forEach()
  • map()
  • some()
归并方法
  • reduce()
  • reduceRight()

Function

Map

Set

WeakSet

WeakMap

Map、Set、WeakMap、WeakSet 见后续文章