(四)js变量类型和计算

365 阅读2分钟

我们先来看几个题目

  • typeof能判断哪些类型
  • 何时使用=== 何时使用==
  • 值类型和引用类型的区别
  • 手写深拷贝

知识点

  • 值类型 vs引用类型
  • typeof运算符
  • 深拷贝

image.png

image.png

  1. 值类型 vs引用类型 栈是一个存储变量的地方
值类型:比较小,可以直接存在栈中;
undefinednullstringnumberbooleansymbolnull比较特殊,笔者认为它是一个原始数据类型,但它的指针指向空地址,js把机械码标签为0的都定义为objectnull0x000,所以也被误认为object)


引用类型:有的很大,所以会把引用地址存在栈中,而实际的值在堆中;
对象,数组,函数(函数:不用于存储数据,所以没有拷贝复制函数这一说,函数内是可执行代码)

image.png

  1. typeof运算符
  • 识别所有的值类型除了null
  • 识别函数(function)
  • 判断是否是引用类型(不能识别引用类型以及null)
    typeof null => 'object'
    typeof [] => 'object'
    typeof {x:1} => 'object'
  1. 深拷贝(主要是递归) 除了手写外,可以自己画一下深拷贝存储值到的过程
const obj1 = {
    age: 20,
    name: 'xxx',
    address: {
        city: 'beijing'
    },
    arr: ['a', 'b', 'c']
}

const obj2 = deepClone(obj1)
obj2.address.city = 'shanghai'
obj2.arr[0] = 'a1'
console.log(obj1.address.city)
console.log(obj1.arr[0])

/**
 * 深拷贝
 * @param {Object} obj 要拷贝的对象
 */
function deepClone(obj = {}) {
 // 先判断obj是不是对象或者数组
    if (typeof obj !== 'object' || obj == null) {
        // 如果不是的话直接返回
        return obj
    }

    // 初始化返回结果,判断是不是数组给对应的初始值
    let result
    if (obj instanceof Array) {
        result = []
    } else {
        result = {}
    }
    
    // 如果是对象或者数组的话 
    for (let key in obj) {
        // hasOwnProperty() 方法用来检测一个属性是否是对象的自有属性,而不是从原型链继承的。如果该属性是自有属性,那么返回 true,否则返回 false
        if (obj.hasOwnProperty(key)) {
            // 保证 key 不是原型的属性
            // 递归调用对象数组!!!
            result[key] = deepClone(obj[key])
        }
    }
    // 返回结果
    return result
}