深入理解JavaScript引用数据类型

发布时间:2023-05-23

一、定义引用数据类型

JavaScript中有两种数据类型:原始数据类型和引用数据类型。原始数据类型包括:字符串、数字、布尔值、null、undefined以及ES6新增的Symbol类型。而引用数据类型则包括了:对象、数组、函数、正则表达式、日期等。 引用数据类型与原始数据类型不同的是,引用数据类型的值在内存中是存储在堆内存中,而在变量中保存的是一个指向堆内存的指针(即引用)。

let obj = {name:"John", age:30};
let newObj = obj; 
obj.age = 40;
console.log(newObj.age);   // 40

上面的代码中,newObj和obj都引用了同一个对象,所以当修改obj的属性时,通过newObj也能看到这个变化。

二、引用数据类型的传递

在JavaScript中,函数参数都是按值传递的,但当参数是引用类型时,传递的是这个引用的地址。所以函数内部修改这个引用所指向的对象是可以被调用者看到的。

let obj = {name:"John", age:30};
function changeAge(obj) {
  obj.age = 40;
}
changeAge(obj);
console.log(obj.age);   // 40

上面的代码中,changeAge函数内部修改了传递进来的obj对象的age属性,所以在函数外部也能看到这个变化。

三、对象的浅拷贝和深拷贝

在JavaScript中,对象的赋值操作其实是一个浅拷贝的过程,也就是说新对象中的属性和原对象中的属性指向的是同一个引用。如果需要复制一个对象的所有属性,可以使用一些方法来进行深拷贝。 下面是一个简单的浅拷贝的例子:

let obj = {name:"John", age:30};
let newObj = obj; 
console.log(newObj === obj);   // true

可以看到newObj和obj相等,因为它们指向的是同一个对象。 而下面是一个深拷贝的例子:

let obj = {name:"John", age:30};
let newObj = JSON.parse(JSON.stringify(obj)); 
console.log(newObj === obj);   // false

可以看到newObj和obj不相等,因为它们指向的是两个不同的对象。

四、数组的引用

数组也是JavaScript中的一个引用类型,和对象一样,对数组的赋值也是一个浅拷贝的过程。

let arr1 = [1, 2, 3];
let arr2 = arr1;
arr1[0] = 4;
console.log(arr2[0]);   // 4

上面的代码中,修改了arr1的第一个元素,通过arr2也能看到这个变化。因为arr1和arr2指向的是同一个数组。

五、函数的引用

JavaScript中的函数也是一个引用类型,函数名也可以看做是一个变量名,用来引用函数的地址。可以将函数作为参数传递给另一个函数,也可以将函数作为另一个函数的返回值。

function foo() {
  console.log("I am foo");
}
function bar(fn) {
  fn();
}
bar(foo);   // I am foo

上面的代码中,将foo函数作为参数传给了bar函数,结果就可以执行foo函数。

六、结语

本文通过多个方面详细地阐述了JavaScript中的引用数据类型,包括引用数据类型的定义、传递、浅拷贝和深拷贝、数组和函数的引用等方面。希望本文能帮助读者更好地理解JavaScript的引用数据类型。