js的值类型和引用类型

js的值类型和引用类型

在ES6中js的数据类型分为两种,分别是值类型和引用类型。

  1. 常见的值类型:undefined,Boolean,number,String,symbol;
  2. 常见的引用类型:Object,Array,null(特殊的引用类型,指针指向空地址),function(特殊的引用类型,但没有存储数据,所以没有拷贝、复制函数这一说);

它们的区别

  1. 存储位置不同,值类型直接存储在栈中,而引用类型的值在堆中,并把存储地址存到栈中;

  2. 将一个值类型的变量赋值给另一个变量时,改变其中一个的值,另一个并不会发生改变;

    let a = 2020
    let b = a
    b = 2021
    console.log(a) // 结果:2020
    console.log(b) // 结果:2021
    
  3. 将一个引用类型的变量赋值给另一个变量时,只要改变了其中一个两个就都会发生改变;

    const a = {
    name: '小明',
    age: 15
    }
    const b = a
    b.age = 20
    console.log(a.age) // 结果:20
    console.log(b.age) // 结果:20
    

typeof运算符

说到数据类型就不得不说一下typeof运算符,它可以用来判断js变量的类型,那么它能够判断哪些类型呢?

  1. 能够识别所有值类型

  2. 能够判断是否是引用类型(不可再细分,会把Array也认为是object)

  3. 能够识别出函数
    也就是说typeof运算符能够识别出7种类型,分别是:undefined,Boolean,number,String,symbol,object,function

    let a
    console.log(typeof a) // 结果: undefined
    const b = 100
    console.log(typeof b) // 结果: number
    const c = '小明'
    console.log(typeof c) // 结果: string
    const d = {
        name: '小红'
    }
    console.log(typeof d) // 结果: object
    const e = ['a', 'b']
    console.log(typeof e) // 结果: object
    const f = Symbol('foo')
    console.log(typeof f) // 结果: symbol
    

深拷贝和浅拷贝

在上面讲值类型和引用类型的区别时,就提到了将一个值类型的变量赋值给另一个变量时,改变其中一个的值,另一个也会发生改变。这种叫做浅拷贝;

什么是浅拷贝?

浅拷贝就是将变量所指向的引用地址直接赋值给另外一个变量,也就是说他们访问的是同一份资源,所以两个变量会相互影响。

什么是深拷贝?

在大多数项目中,我们需要的是两个变量,并不会相互影响,所以需要用到深拷贝;
深拷贝会重新创建一个字段和值相同的新的数据,并把其引用地址放回给我们定义的变量。

	function deepClone (obj) {
    if (typeof obj != 'object' || obj == null) {
        // 如果是值类型或者为 null
        return obj;
    }
    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 testObj = {
    name: '小明',
    age: 10,
    address: ['北京','上海'],
    score: {
        math: 89,
        english: 91
    }
}
const a2 = deepClone(testObj);
a2.score.math = 100

console.log('testObj的math',testObj.score.math)  //  结果:testObj的math 89
console.log('a2的math',a2.score.math)  //  结果:a2的math 100

我们发现在改变了第二个变量后第一个并没有发生变化。

猜你喜欢

转载自blog.csdn.net/xiaobo_666666/article/details/112365236