js的数据类型有哪些
js数据类型按照存储方式来区分的话,可分为基本数据类型和引用数据类型,基本数据类型 string、number、Boolean、null、undefined、symbol(ES6新增);引用数据类型实际上就是广义的object,有object、array、map、set等。我做了一张图如下:

基本数据类型
undefined
- undefined 类型只有一个特殊值:undefined。
- 当通过var、let 声明的变量没有赋初始值的时候,默认值为undefined。
null
- null类型只有一个特殊值:null。
- nul 实际上表示一个空对象指针(这就是为什么我们使用typeof null 返回的是object)
- 在定义将要保存object值的时候,初始化建议使用null。
boolean
- boolean 有两个字面量:true、false。
number
js所有数字都是双精度浮点数,
- 浮点数占用内存是整数的两倍。如果后面是.00这样的情况,会自动存成整数
- 浮点数精确度最高可达到17位小数
- 如果值超出了js可以表达的范围,这个数值会被自动转化为infinity,负数为-infinity。确定一个值是不是有限大,可通过isFinite()函数
- NaN,标识不是数值,用于表示本来要返回数值的操作失败了。
- 0除以任何数 都是 NaN
- 非0除以0为infinity
- NaN不等于包含NaN在内的任何值
- isNaN() 函数判断是不是不是数值 如: isNaN(10) false
- 数值转化
- Number()
- boolean值 true返回1,false返回0
- 数值 直接返回
- null 返回0
- undefined返回 NaN
- string 如果是数值字符 直接返回,浮点数数值字符串直接返回浮点数。空字符串返回0,其他返回NaN
- Number.parseInt()
- string 最前面的空格会忽略,第一个字符如果不是数字字符、加减号,会立即返回NaN。空字符串也返回NaN。
- 如果第一个字符是数字字符或加减号,会继续向后检测,直到字符串末尾。碰到非数字字符,会被忽略。返回有效数字
- 由于小数点不是有效数字字符,所以parseInt()返回整数。
- Number.parseFloat()
- 类似于parseInt()
- 但parseFloat() 第一个小数点是有效的,所以返回浮点数。
- Number()
- 小心浮点运算中精度陷阱
- 01+ 0.2 === 0.3 //false
- 尽量选择整数计算,如果计算货币,我们可以转化小单位再进行计算
string
- 可以通过length获取长度。
- 字符串是不可变的,一旦创建就不能再更改。如果需要修改变量需要先销毁原始值,再去更换新值。
- 转换为字符串
- toString()
- Boolean、number、string、object 都有toString方法,可使用 x.toString()转化为字符串
- null、undefined没有tostring方法
- String()– 值有可能是null、undefined使用
- 如果值有toString()方法,就调用toString()方法。
- unll 返回 “null”、undefined返回”undefined”
- toString()
- 模板字面量(``)
- 模板字面量不是字符串,而是一种特殊的表达式。
- 可通过${}来插入值,所有插入值都会强制转为字符串。
- 方法
- concat() 连接多个字符串,str.concat(str2, [, …strN])
- endsWith() 判断结尾是不是当前字符串,默认最后,指定长度也可,str.endsWith(searchString[, length])
- includes() 判断字符串是否包含另一个字符串
- indexOf() 返回第一次出现指定字符串的索引值
- match() 返回匹配正则表达式的结果
- padEnd() 字符串补全,str.padEnd(targetLength [, padString]),padString没有的时候 补空格
- repeat() 构造返回新的字符串 str.repeat(count)
- replace() 替换字符串
- search() 通过正则表达式搜索字符串,如果有返回索引下标,没有返回-1 tr.search(regexp)
- slice() 提取字符串一部分 不改变原字符串 str.slice(beginIndex[, endIndex]) 如 str.slice(2, -1) 提取第三个字符到倒数第一个字符。
- split() 指定分隔符将字符串切割成数组,str.split([separator[, limit]])
- startsWith() 判断字符串是否以给定子字符串开头str.startsWith(searchString[, position])
- substring() 方法返回一个字符串在开始索引到结束索引之间的一个子集 str.substring(indexStart[, indexEnd])
- toLocaleLowerCase() 返回小写
- toLocaleUpperCase() 返回大写
- toLowerCase() 会将调用该方法的字符串值转为小写形式,并返回。
- toUpperCase() 方法将调用该方法的字符串转为大写形式并返回
- toString() toString() 方法返回指定对象的字符串形式。
- trim() 从一个字符串的两端删除空白字符。
- valueOf() 返回 String 对象的原始值
引用数据类型
Date

RegExp
Array
Object
Function
Map
WeakMap
Set
WeakSet
基本类型和引用类型的区别
-
基本数据类型的值不可改变
任何方法都不可以改变基本数据类型的值,如:
let str = "str"; str.repeat(3); console.log(str) // strstr并没有改变,而是返回了一个新的字符串,再比如:
let name = "name" name.age = 15 name.fuc = function() { } console.log(name) // name由上可知,基本类型不可以被添加属性和方法,从而得知,基本类型的值是不可改变的。
-
基本类型的比较是值的比较,引用类型的比较是引用的比较
-
基本数据类型和引用数据类型的存储位置不同,基本类型存到占内存,引用类型存到堆内存
一些小细节
原始类型优于封装对象
标准库提供了构造函数来封装布尔值、数字和字符串作 为对象。
- 你可以通过 s = new String(“hello”) 创建一个字符串对象,也可以通过s+”world” 创建一个新的字符串,但是s是一个真正的对象,typeOf s 结果为object。
- 当对原始值提取属性和进行方法调用时,它表现得就像已经使用了对应 的对象类型封装了该值一样。这种隐式封装的一个奇怪后果是你可以对原始值设置属性,但是对其丝毫没有影响。
避免对混合类型使用==运算符
- 当参数类型不同时,== 运算符应用了一套难以理解的隐式强制转换规则。
- 使用 === 运算符,使读者不需要涉及任何的隐式强制转换就能明白你的比较运算。
- 当比较不同类型的值时,使用你自己的显式强制转换使程序的行为更清晰。