二 js变量类型和计算

180 阅读3分钟

值类型

let a = 100;
let b = a;
a = 200;
console.log(b) // 100

image.png

结论:

1 值类型存储在栈内存中,a和b之间互相赋值,a改变,b不会改变(各不相干)

2 如果想象引用类型一样赋值就需要用到深拷贝

引用类型

let a = {age: 20};
let b = a;
b.age = 21;
console.log(a.age) // 21

image.png

结论:

引用类型: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