js堆栈问题

在日常开发中常有这样一个需求

一、基本类型

初始化多个变量为默认值,如下

    let defaultVal =0;
    var numOne=defaultVal;
    var numTwo=defaultVal;
    numOne+=2;
    numTwo+=5;
    console.log(numOne,numTwo)//结果2,5

对于上面这个代码,两个变量在分别处理后互不影响

因为defaultVal在js储存方式中属于基本类型(boolean,number,string,undefined,null,symbol

解析:每个变量都有一个具体的地址存储值,存储在中,即按值访问的,就是说你可以操作保存在变量中的实际的值。

从一个变量向一个变量复制时,会在栈中创建一个新值,然后把值复制到为新变量分配的位置上,这也就是默认值赋值给两个新变量后再修改两个变量互不影响的原因。

也就是说在赋值后栈中有了三个变量并且都有自己的值

二、引用类型

而在我们需求变了以后,修改代码如下

  
let defaultVal =[0,0,0,0,0];
let defaultUser={
    Name:'Jone',
    Age:'18'
};
    
var numOne=defaultVal;    
var numTwo=defaultVal;    
numOne[0]=6;
   
console.log(numOne,numTwo)
//结果[6,0,0,0,0],[6,0,0,0,0]

var codeMonkey=defaultUser;
var proManager=defaultUser;
proManager.Name='Mr.Steve';

console.log(codeMonkey,proManager)
//结果也都是{Name: "Mr.Steve", Age: "18"}

如代码所示,定义两个不同变量后将默认值赋给它们后再处理将会影响对方

因为defaultVal、defaultUser在js储存方式中属于引用类型(对象object,数组array,函数function

解析:引用数据类型值指保存在堆内存中的对象。也就是,变量中保存的实际上的只是一个指针,这个指针指向内存中的另一个位置,该位置保存着对象。访问方式是按引用访问,也是由此它们中修改任意一个变量都是在修改堆中同一对象,所以即使是在赋值给不同变量后修改对方仍然会相互影响,如下图

三、End

在实际开发中我们难免会有需要用到引用类型的值来做默认赋值。

那么怎么去赋值才可以做到像基本类型那样赋值在操作相互不影响?

简单易懂的处理方式就是:

方法一:(注意这是便于理解的方法!,实际开发可用第二种方法)

  
let defaultVal =[0,0,0,0,0];
let defaultUser={
    Name:'Jone',
    Age:'18'
};
    
var numOne=copyArr(defaultVal);    
var numTwo=copyArr(defaultVal);    
numOne[0]=6;

function copyArr(oldArr){
    let newArr=[];
    for(var i in oldArr){
        newArr.push(i);
    }
    return newArr
}

方法二:'...'在对象前,你就理解为遍历了这个对象的每一项然后返回。注意数组一定要[]括起来,对象要{}括起来,因为返回的是每一项的子项并非一个新的对象。

let defaultVal =[0,0,0,0,0];
let defaultUser={
    Name:'Jone',
    Age:'18'
};
    
var numOne=[...defaultVal];    
var numTwo=[...defaultVal];
numOne[0]=6;

var codeMonkey=[...defaultUser];    
var proManager=[...defaultUser];
proManager.Name='Mr.Steve';
发布了25 篇原创文章 · 获赞 10 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/xj932956499/article/details/103236156