JavaScript堆栈之传值与传引用详解

1、JavaScript两大变量类型

JavaScript的变量分为两大类型:基本类型和引用类型。

基本类型:存放在栈内存中的简单数据段,数据大小确定,内存空间大小可以分配。5种基本数据类型有Undefined、Null、Boolean、Number 和 String,它们是直接按值存放的,所以可以直接访问。

引用类型:存放在堆内存中的对象,变量实际保存的是一个指针,这个指针指向另一个位置。每个空间大小不一样,要根据情况开进行特定的分配。

2、计算机内存模型——堆与栈

计算机内存模型模型也分为两种

栈:用来放置基本类型(Number Boolean String undefined null)。

堆:用来放置引用类型(Object Function Array Date RegExp)。

3、JavaScript堆栈

有了上面的基础知识铺垫,我们就可以说一些有意思的东西了。当我们创建一个字符串的时候,由于字符串是基本类型所以其值分配到了栈当中。当我们创建一个数组的时候,由于是引用类型。先会在堆中创建对象。然后把堆中的地址放到栈里面。代码如下:

1
2
var name ="foo";
var hobby=["唱歌","跳舞"];

将这段代码翻译成图。

js内存

4、JavaScript传值和传引用

在JavaScript当中,基本类型是传值,引用类型是传引用。

1
2
3
4
5
6
var hobby=["唱歌","跳舞","看书"];
var hobby2=hobby;
hobby2.pop(); //删除最后一个元素并返回这个被删除的元素。
console.log(hobby); //["唱歌", "跳舞"]
console.log(hobby2); //["唱歌", "跳舞"]
console.log(hobby==hobby2);

从上面的代码我们可以看到,当hobby赋值给hobby2的时候,实际上只是把hobby对象的引用地址传给它了。也就是说hobby和hobby2其实共用同一个对象。

js引用

所以我们对hobby2的修改,也就是对hobby做了修改。

我们再来看基本类型的情况。

1
2
3
4
5
6
var name="foo";
var name2=name;
name2="bar";
console.log(name); //foo
console.log(name2); //bar
console.log(name==name2); //false

这段代码说明,name和name2不是同一个值。他们之间互不影响。因为在name赋值给name2的时候,会给name2新建拷贝一个foo的值。然后让name2指向这个foo这个值。

js堆栈