JS 变量与数据类型
JavaScript 数据类型
值类型
:number、string、null、boolean、undefined、BigInt、Symbol引用类型
:object,包含 object、array、date、function 等
JavaScript 中的真假值
truly 值
:两次取反(非运算)等于 true 的值,!!x === true
falsely 值
:两次取反(非运算)等于 false 的值,!!x === false
假值如下:
- null
- undefined
- ‘’ 空字符串
- +0、-0
- NaN (Not a Number)
- false
除了以上的假值外,其他值都可以认为是truly
;
typeof 可以判断哪些类型
typeof 可以判断除了 null 以外的所有值类型
,以及引用类型
中的 function 和 object;
- number
- string
- undefined
- boolean
- bigInt
- symbol
- function
- object
要判断引用类型,可以使用 instanceof;
为什么 typeof null 返回的是 object
JavaScript 底层存储变量时,使用变量机器码的低 1 ~ 3 位存储其类型信息;
类型标签 | 类型 | 说明 |
---|---|---|
000 | 对象 | |
1 | 整数 | |
010 | 浮点数 | |
100 | 字符串 | |
110 | 布尔值 | |
undefined | 用 -2^30 整数表示 | |
null | 所有机器码为 0 |
上表可以看到,对象的类型标签是 0,而由于 null 的所有机器码均为 0,因此,null 的类型标签也可以认为是 0,所以 typeof 在判断类型时,就把 null 当作了对象;
值类型和引用类型的区别
- 存储位置不一样
- 值类型的变量保存在栈内存中,通常,在代码段执行结束后,值类型的变量会被销毁;
- 引用类型的变量名保存在栈内存中,但变量的值会存储在堆内存中,引用类型的变量不会自动销毁,而是在没有被引用时,由垃圾回收机制释放;
- 复制方式不一样
- 值类型的变量之间复制是深拷贝,修改不会相互影响;
- 引用类型的变量之间直接赋值实际上是引用传递,只是浅拷贝,修改会互相影响;
- 值类型的变量无法添加属性和方法,而引用类型则可以;
- 比较方式不一样
- 值类型的比较是值的比较,值相等则相等,== 在比较时可能会隐式类型转换,=== 则需要类型与值完全相等;
- 引用类型的比较是引用地址的比较,即使内容相同,但地址不同,也不相等;
- 当作函数的参数时,传递方式不同
- 值类型作为函数参数时,实参会复制给形参,数据独立,互不影响;
- 引用类型作为函数参数时,传递给形参的就是实参的引用地址,修改会相互影响;
简单实现深拷贝
1 | /** |
Object.assign 不是深拷贝
Object.assign 是浅拷贝,对于属性值为引用类型的值,只会拷贝其引用地址;
1 | const obj1 = { a: 10, b: 20, c: { x: 100, y: 200 } }; |
结果如下:
修改值为基本类型的属性不会互相影响,而修改值为引用类型的属性时则会相互影响;
何时使用 ====,何时使用 ==
除了判断是否等于 null 或 undefined,其他地方一律用 ===;
- 判断对象的属性是否存在可以使用 ==;
- 判断函数的参数是否存在可以使用 ==;
var 和 let const 的区别
- var 属于 es5 规范;
- let、const 属于 es6 规范;
- var 有变量提升;
- let、const 有块级作用域;
- var、let 声明的是变量,可修改,const 声明的是常量,不可修改;
列举强制类型转换和隐式类型转换
- 强制类型转换:parseInt、parseFloat、toString、Number、String 等;
- 隐式类型转换:if、逻辑运算、==、+ 拼接字符串等;
手写深度比较,模拟 lodash 的 isEqual
1 | /** |