值传递&引用传递

221 阅读2分钟

前言

js 中的值传递和引用传递是一个很重要的概念,也是很多面试题的考察点,本文将详细介绍 js 中的值传递和引用传递的区别,以及如何在实际开发中使用这两种传递方式。这个概念很简单,但是实际开发中很多人都容易混淆。

值传递

值传递指的是重新开辟一块内存空间,将旧变量值复制到新的内存空间中,新变量和旧变量就互不影响了。在 js 中,基本数据类型(number、string、boolean、null、undefined、symbol)都是值传递。

let a = 1;
let b = a;
b = 2;
console.log(a); // 1
console.log(b); // 2

引用传递

指的是新变量的内存地址指向旧变量的内存地址,它们共享同一块内存空间,修改其中一个变量的值,另一个变量的值也会发生变化。在 js 中,引用数据类型(object、array、function)都是引用传递。

let a = { name: "张三" };
let b = a;
b.name = "李四";
console.log(a, b); // { name: "李四" }, { name: "李四" }
a.name = "王五";
console.log(a, b); // { name: "王五" }, { name: "王五" }

练习题

export let a = 1;
export function increase() {
  a++;
}
import { a, increase } from "./module.js";
console.log(a);
increase();
console.log(a);

具名导入的变量都是引用传递,所以 a 的值会发生变化。

备注:

具名导入的变量‌是指在JavaScript中使用import语句时,通过指定变量的名称来导入模块中的特定导出项。这种方式允许开发者明确地指定要从模块中导入的内容,并且可以控制导入的变量名,从而使得代码更加清晰和易于管理。

语法和使用方法

在ES6及更高版本中,可以使用具名导入来导入单个变量、函数、类等。语法如下:

javascriptCopy Code
// 导入单个变量
import { variableName } from 'module';

// 导入多个变量
import { variable1, variable2 } from 'module';

// 导入函数
import { functionName } from 'module';

示例

假设有一个模块math.js,其中导出了两个函数addsubtract

javascriptCopy Code
// math.js
export function add(a, b) {
  return a + b;
}
export function subtract(a, b) {
  return a - b;
}

在另一个文件中,你可以这样导入这些函数:

javascriptCopy Code
// app.js
import { add, subtract } from './math';

console.log(add(1, 2)); // 输出 3
console.log(subtract(5, 3)); // 输出 2
1 2

与默认导入的区别

默认导入‌和‌具名导入‌的主要区别在于导入语句的写法:

  • 默认导入‌使用import moduleName from 'module'的语法。例如:import math from './math';

  • 具名导入‌使用import { exportName } from 'module'的语法。例如:import { add, subtract } from './math';

const testFunc = () => {
  let a = 1;
  let obj = { name: "pzj" };
  let changeVars = () => {
    a++;
    obj.name = "codepzj";
  };
  return {
    a,
    obj,
    changeVars,
  };
};

const { a, obj, changeVars } = testFunc();
console.log(a, obj);
changeVars();
console.log(a, obj);

a 是基本数据类型,所以是值传递,obj 是引用数据类型,所以是引用传递。

1 { name: "pzj" }
1 { name: "codepzj" }

总结

基本数据类型(number、string、boolean、null、undefined、symbol)是值传递,引用数据类型(object、array、function)是引用传递。具名导入的变量都是引用传递。