基础巩固js值类型和引用类型

Posted deepdarkdeveloper

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基础巩固js值类型和引用类型相关的知识,希望对你有一定的参考价值。

示例

值类型

let a = 100;
let b = a;
a = 200;
console.log(b); // 100 (互不影响)

引用类型

let a = { age: 20 };
let b = a;
a.age= 21;
console.log(b.age); // 21 (b.age随a.age的改变而改变)

存储方式

值类型

技术图片
js变量存储在栈中,至于怎么存储咱先不管(毕竟我也不懂),这是js引擎的事情。
如图所示,key为变量名,value为存储内容,值类型变量的值直接存储在value中,a的值改变后并不会影响b的值。

引用类型

技术图片
在栈中,引用类型存储的是内存地址,同时内存地址指向堆中的值,
简单地讲:引用类型a -> 内存地址1 -> a的值,此时若执行let b = a;,则是把b的内存地址指向了a的内存地址,而这个内存地址指向同一个值,所以a的值改变的时候,b的值也随之改变。

图片来源:学习资料

为什么引用类型要搞个内存地址?
众所周知最常见的引用类型是对象和数组,数组长度和对象属性数量是没有限制的,甚至可以嵌套,如果像存储值类型那样存储引用类型(没有内存地址,直接存储在栈中),那计算机怕是要炸了。

常见值类型和引用类型

// 常见值类型
let a; // undefined
const n = 100; // Number
const s = '100'; // String
const b = true; // Boolean
const s = Symbol('s') // Symbol(es6)
// 常见引用类型
const obj = { value: 100 }; // Object
const arr = [ 1, 2, 3 ]; // Array
const n = null; // 特殊引用类型,指针指向空地址
function fn() {} // 特殊引用类型,但不用于存储数据,所以不考虑深拷贝浅拷贝的问题

深拷贝

  • JSON.parse(JSON.stringify(obj))
    最简单的方式,但会忽略undefined,function,RegExp

  • Object.assign()或解构赋值(const a = {...obj}, const b = [...arr])
    只适合只有一层没有嵌套的对象或数组

  • 递归
const deepCopy = obj => {
    let copy = Array.isArray(obj) === true ? [] : {}
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            if (typeof obj[key] === 'object') {
                copy[key] = deepCopy(obj[key])
            } else {
                copy[key] = obj[key]
            }
        }
    }
    return copy
}

以上是关于基础巩固js值类型和引用类型的主要内容,如果未能解决你的问题,请参考以下文章

关于js的引用类型和基本类型

JavaScript系统学习小结——变量作用域和内存问题

JavaSE复习基础巩固

js基础之基本数据类型

JS基础类型和对象,分别是按值传递还是按引用传递?

C#中的引用传递和值传递。