JavaScript在内存分配管理上使用栈内存和堆内存,简单的基本数据类型的数据一般存储在栈内存中(其值有固定的大小范围),而像复杂的 Object 类型的数据则使用堆内存来存储(其大小不固定如数组对象等)。

栈内存中存储js声明的变量名和变量值,由于基本数据类型的值直接存储在栈内存中可以直接获取数据的值,而Object类型存储在堆内存中,栈内存存放的是使用Object类型数据名和该数据在堆内存中的地址值,相当于引用该种类型的数据。

javascript的存储位置 js对象存储在哪里_堆内存

正是由于Object类型的数据是通过地址值引用的,在js开发中会出现一些问题,比如:

// 引用类型复制变量
        var person={//堆内存中存储对象数据{name:'name',age:'age'},person保存的值是数据在内存中的地址值
            name:'name',
            age:'age'
        }
        var student=person//复制person变量值即地址值
        student.name='student'
        console.log(person.name) //student

当引用类型的数据被复制时,复制的是其引用的地址值,变量person和student共用一个对象,当student.name属性被修改时,存储在堆内存中的对象的属性即被修改,因此才会出现 深拷贝和浅拷贝 的问题。

如何处理Object类型的问题

javascript的存储位置 js对象存储在哪里_数据_02

// 通过浅拷贝来实现
 var person={
            name:'name',
            age:'age'
        }
        var student={...person}// ...浅拷贝赋值里面的值
        student.name='student'
        console.log(person.name) //name

基本数据类型(栈空间)

// 基本类型复制变量
var a = 10;
var b = a;
b = 20;

a // 10
b // 20

对于基本数据类型,栈中存储的就是它自身的数据值,将 a 变量的值赋值给 b 变量,就是将 a 的值10复制了一份给 b ,存储在栈内存中。


JS中调用函数时传递参数,是值传递,只是基本数据类型传递的值即是在内存中保存的数据,而Object类型的数据传递的值是其数据在内存中保存的地址值。参考如下代码:

var a=3;//全局变量 a 值为3
        function fn(a) {//局部变量 a,将全局变量 a 的值3复制给局部变量 a
            a=a+1;   //局部变量 a 值加1,其值为 4
        }
        fn(a);//将全局变量 a 的值3传递给局部变量 a
        console.log(a);//3 打印的是全局变量 a

        function fn2(obj) {//局部变量 obj 与全局变量 obj 引用同一个对象
            obj.age=13;
            console.log(obj.name);// Tom
        }
        var obj={name:'Tom'};
        fn2(obj);//调用fn2函数,传递obj对象值即保存在内存中的地址值
        console.log(obj.age);// 13