JS分两种数据类型:
(1)基本数据类型:Number、String、Boolean、Null、 Undefined、Symbol(ES6),这些类型可以直接操作保存在变量中的实际值。
(2)引用数据类型:Object(在JS中除了基本数据类型以外的都是对象,数据是对象,函数是对象,正则表达式是对象)
基本数据类型(存放在栈中)
基本数据类型是指存放在栈中的简单数据段,数据大小确定,内存空间大小可以分配,它们是直接按值存放的,所以可以直接按值访问,如下例子
var a = 10;
var b = a;
b = 20;
console.log(a); // 10值
console.log(b); // 20值
下图演示了这种基本数据类型赋值的过程:
image.png
引用数据类型(存放在堆内存中的对象,每个空间大小不一样,要根据情况进行特定的配置)
引用类型是存放在堆内存中的对象,变量其实是保存的在栈内存中的一个指针(保存的是堆内存中的引用地址),这个指针指向堆内存。换言之,引用类型数据在栈内存中保存的实际上是对象在堆内存中的引用地址。通过这个引用地址可以快速查找到保存中堆内存中的对象,如下例子
var obj1 = new Object();
var obj2 = obj1;
obj2.name = "我有名字了";
console.log(obj1.name); // 我有名字了
下图演示了这种引用数据类型赋值的过程:
image.png
再看个结合的例子:
var a = [1, 2, 3, 4, 5];
var b = a;//传值
var c = a[0];
console.log(b)
console.log(c)
b[4]=6;
c=7;
console.log(a[4])
console.log(a[0])
console.log(c)
从上面我们可以得知,当我改变b中的数据时,a中数据也发生了变化;但是当我改变c的数据值时,a却没有发生改变。
这就是传值与传址的区别。因为a是数组,属于引用类型,所以它赋予给b的时候传的是栈中的地址(相当于新建了一个不同名“指针”),而不是堆内存中的对象。而c仅仅是从a堆内存中获取的一个数据值,并保存在栈中。所以b修改的时候,会根据地址回到a堆中修改,c则直接在栈中修改,并且不能指向a堆内存中。
所以衍生出来的另一个值得探讨的问题“深浅拷贝”:
详细请参考博客:https://www.jianshu.com/p/3e7a628a276c
本文参考博客:
https://www.cnblogs.com/c2016c/articles/9328725.html
网友评论