引言
数据类型决定了 JavaScript 如何存储、操作和管理数据,深入理解数据类型,是写出高质量 JavaScript 代码、避免隐式 bug、进阶学习闭包/原型/异步等高级特性的必经之路。所以本文来讲解 JavaScript 的数据类型的用法与区别。
JavaScript 中的数据类型
js 中有 基本类型 和 引用类型。
| 类型分类 | 常用类型 |
|---|---|
| 基本类型 | string,number,boolean,undefined,null,bigInt,Symbol |
| 引用类型 | Array, Object, Function, Date |
基本类型
- string(字符串)
let str = 'hello world'
变量 str 就是 string 类型。
string 类型的 增加 方法有:
let str2 = str + ' js'
let str2 = '${str} js'
//空格也是string类型,也会增加进去
console.log(str2)
输出结果为:
string 类型的常用方法还有:
console.log(str.at(0))
at(0) 输出 str 中下标为 0 的字符:
console.log(str.slice(0,7))
slice方法是左闭右开的,所以slice(0,7)输出下标 0——7 的字符,第7个不输出,也就是输出:
其中空格也作为字符输出。
- number(数字)
number类型是:
let num = 123
变量 num 就是 number 类型。
number 类型的常用方法:
number类型相加:
let num2 = num + 0.1
console.log(num2)
输出结果为 number 类型:
number 类型与 string 类型相加:
console.log(num + '5')
输出结果为 string 类型:
因为在运行 js 代码的 v8 引擎中,输出时会将与 string 类型相加的类型转换为 string 类型。
number 类型 转换为 string 类型 的方法:
console.log(num.toString())
to string 方法会将 number 类型转换为 string 类型。
number 类型相加还有方法 Number():
let n = 1
let m = 2
cosole.log(n + Number(m))
这也会输出 number 类型 : 3。
但如果变量 m 是一个 string 类型:
let n = 1
let m = 'm'
console.log(n + Number(m))
就会输出:
意思是not a number,非数字,但 NaN 这个输出值本身是一个 number 类型值。
number 类型有一个上限,就是 2**53 ,超过这个值就不能增加了。
console.log(9007199254740992 + 1) // 2**53 + 1
输出值还是 2**53:
- bigInt(大整数)
因为 number 类型最大值为 2**53 ,所以后来 js 又加了个类型 bigInt。
let b = 123123123n
let c = 9007199254740992n // 2**53
console.log(b + c)
输出:
bigInt 类型可以进行 2**53 以外值的计算。
- boolean(布尔)
在 boolean 类型中,判断条件问为 true 和 false,falsy 值在布尔判断中被视为 false。
| falsy值 | 说明 |
|---|---|
| false | 布尔假 |
| 0 | 数字零 |
| “” | 空字符串 |
| null | 空对象 |
| undefined | 未定义 |
| NaN | 非数字 |
其他值则被视为 true。
if(true){
console.log('ikun')
}
判断成功输出:
if(false){
console.log('ikun')
}
判断失败,不输出。
- undefined
undefined 是未初始化的变量默认值。
let u = undefined + ' ikun'
console.log(u)
输出:
- null
null 是开发者主动设置的"空值",表示这里应该有个对象,但目前没有,用来初始化对象。
let n = null
7.Symbol
Symbol 是唯一标识符,用来避免冲突:
let s = Symbol('hello')
let p = Symbol('hello')
console.log(s == p);
输出结果为:
所有的 Symbol 都是不同的。
‘=’ 的用法
= 是赋值,== 是相等运算符,但它会进行类型转换后再比较(会将两边都转换为 number 类型), === 是全等运算符,它不会转换类型,直接进行比较。
let b = 1
let c = '1'
console.log(b == c)
输出结果为:
因为它将变量 c 的类型转换为 number 类型后再与变量 b 比较,所以变量 b 和变量 c 相等。
let b = 1
let c = '1'
console.log(b === c)
输出结果为:
=== 是全等运算符,要类型也一样才相等。
引用类型
1.Array(数组)
var arr = ['a', 'b', 1, 2]
在数组尾部增加:
arr.push(3) // 在尾部增加一个 3
在数组头部增加:
arr.unshift(0) // 在头部增加一个 0
删去数组尾部:
arr.pop() // 删除尾部 2
删去数组头部:
arr.shift() // 删除头部 ‘a’
还有 splice 方法用来删除和插入。
删除:
arr.splice(1,2) // 从下标 1 开始,删除 2 个
插入:
arr.splice(2,0, 'ikun') //从下标 2 开始,删除 0 个 ,加入 ‘ikun’
数组的修改:
arr [2] = 10 // 将下标 2 的变量改为 10
2.Object(对象)
var obj = {
name: 'ikun',
age: 18,
like: {
one: '唱'
two:'跳'
three: {
skill: [ 'rap', '篮球']
}
}
}
对象里属性名的属性值也可以是 Object 类型 和 Array 类型。
obj.boyFriend = 'kunkun' //向对象中加入 boyFriend:'kunkun'
delete obj.boyFriend // 删除对象中的 boyFriend
v8 的执行过程
- 创建一个调用栈 (用来存放预编译的过程)
- 在调用栈中,存入 xx 执行上下文
- 执行代码, 将原始值 存入 栈中,如果遇到引用类型的值,则将值存入堆空间,并生成一个引用地址,将引用地址存入栈中,这样设计的好处,既保证了栈不用设计得很大从而影响 v8 的执行效率,又不会爆栈
因为 数组 和 对象 等引用类型比较复杂,里面可能存的东西有点多,所以要将值存入堆空间。