值类型
let a = 100;
let b = a;
a = 200;
console.log(b) // 100
结论:
1 值类型存储在栈内存中,a和b之间互相赋值,a改变,b不会改变(各不相干)
2 如果想象引用类型一样赋值就需要用到深拷贝
引用类型
let a = {age: 20};
let b = a;
b.age = 21;
console.log(a.age) // 21
结论:
引用类型:a = {age: 20} 栈:在栈中a的值value存储的是内存地址1 堆:在堆中分配一个 内存地址1,它的value为 {age: 20} let b = a, 那么b也指向 内存地址1 b 变 a也变
引用类型
const obj = {x: 100};
const arr = ['a', 'b', 'c'];
const n = null // 特殊引用类型,指针指向空地址
// 特殊引用类型,但不用于存储数据,所以没有'拷贝、复制函数'一说
function fn(){}
值类型和引用类型
- 值类型一般存储的数据比较小,占用空间比较少,复制时不会对性能造成很大的影响。
- 引用类型如果像值类型那样存储的话,存储地址太大,不好管理,复制时直接复制值会导致复制非常慢
- 区别:值类型、引用类型区别:值类型就是原始值,存储在栈;引用类型栈存放地址值,指向栈空间
- 总结:栈从上往下存,堆从下往上存;基本不会重合
深入分析
- 值类型值存栈中,引用数据类型 地址存栈中,值存堆中;
- 对象放在堆中,因为对象体积比较大,栈里面一般不放大体积的数据
- 变量赋值实际是用栈中存放的值/地址进行赋值
- 值类型赋值内存比较小,对造成的性能不会有问题,所以可以直接赋值
- 引用类型的Json可以是上千上万行代码,一般造成内存比较大,因此也需要将栈和堆严格分离出来,引用类型如果像值类型一样直接存储复制值,占内存耗时
typeof
类型判断
- 识别所有值类型
- 识别函数
- 判断是否是引用类型(不可再细分)
string number boolean undefined function null
对于null object array 统一返回 object
== 与 ===
===绝对相等 转换类型,==存在隐式相等 判断类型
手写深拷贝
变量类型:原始值 string、number、boolean、symbol、unddefined、null
引用值:array, object(function null特殊引用类型)
- 深拷贝代码
// 先判断值类型和引用类型
// 再判断是数组还是对象
// 递归
function deepClone(obj){
if(typeof obj !==Object || obj == null){
return;
}
let result;
if(obj instanceof Array){
result = [];
} else {
result = {};
}
for(let key in obj){
if(obj.hasOwnProperty(key)){
result(key) = deepClone(obj(key))
}
}
return result
}
变量计算
类型转换
- 字符串拼接
const a = 100 + 10 // 110
const b = 100 + '10' // 10010
const c = true + '10' // true10
- ==
100 == '100' // true
0 == '' //true
0 == false // true
false == '' // true
null == undefined // true
// 除了 == null 之外,其他都一律用 ===,例如
const obj = {x: 100}
if(obj.a == null){}
// 相当于 if(obj.a === undefined || obj.a === null)
obj == null 相当于 obj === null || obj === undefined
- if语句和逻辑运算
!!0 // true