JavaScript 是按引用传递还是按值传递类型
在深入探讨 JavaScript 编程语言是否是按引用类型传递之前,让我们先看看按值传递和按引用传递之间的区别。
当我们进行赋值操作或处理函数本身时,这些东西通常会出现。因为大多数时候,我们执行赋值操作,创建各种函数,并将多个变量传递给这些函数,了解这些东西的内部工作原理将使我们对编程语言有更深入的了解。
每当我们将一个变量的值分配或传递给另一个变量或函数时,它被称为按值传递。当我们将一个变量的地址分配或传递给另一个变量或函数时,它被称为通过引用传递。
现在我们已经看到了值传递和引用传递类型的基本定义,让我们进一步了解它们在下面的示例中的使用方式。
请注意
,JavaScript 中有两种数据类型:原始数据类型和非原始数据类型。原始数据类型包括数字、布尔值、字符串、undefined 和空值。
这些数据类型没有像我们在对象或数组中那样的任何预定义方法。原始数据类型是不可变的;这意味着无论何时你将一个原始变量的值存储或分配给另一个变量并对第二个变量的值进行一些修改时,第一个变量的值都不会改变。它将保持原样,直到并且除非你更改该变量本身的值。只有这样,第二个变量才会改变。
你可以在 MDN 上找到与原始数据类型相关的更多信息。
// Example 1
let a = 10;
let b = a;
b = b + 1;
console.log(a);
console.log(b);
// Example 2
let name = "Google";
let greet = (val) => {
val = "Hi " + name +"!";
return val;
}
console.log(name);
console.log(greet(name));
输出:
10
11
Google
Hi Google!
借助下图可以更好地理解上面的代码。请注意,它只解释了第一个代码示例;第二个示例的工作方式与示例一大致相同。
在我们的第一个示例中,我们有两个变量:a
和 b
。我们为变量 a
分配了数值 10
;这将在内存中为变量 a
分配一个空间,由具有地址 0x01
的黄色表示(这只是本示例中采用的任意地址)。
然后,我们将变量 a
分配给变量 b
。这个过程将为变量 b
分配新的内存空间。在这里,它将存储变量 a
的值,即 10
。
从上面的例子中,我们可以清楚地看到变量 a
和 b
的地址是不同的,这意味着它们在内存中分配了不同的空间。这个结果意味着,无论何时你将变量 b
的值更改或修改为 b = b + 1
,变量 a
内的值都不会改变。只有变量 b
的值会改变,它会变成 11
,因为我们将它加一。
在我们的第二个例子中,我们有一个变量 name
,里面有一个值 Google
。我们还有一个名为 greet()
的函数,它接受一个字符串值作为参数并返回一个新字符串。作为此函数的参数,我们传递变量 a
(请注意,传递变量意味着传递其值而不是其地址)。Google
值将存储在名为 val
的函数局部变量中。
目前,变量 val
包含值 Google
。在函数中,我们将此值更改为 Hi Google!
然后返回这个值。现在,如果你输出 name
变量值和函数,以及返回值,它们都会不同。name
变量保持不变,因为 name
和 val
变量存储在不同的位置,我们只是将值 Google
传递给函数和地址。
之前,我们已经看到了按值传递的定义,它表示我们只在赋值期间或将变量传递给函数时传递变量的值。上面的两个例子在实践中证明了这一点。
非原始数据类型由数组、对象或类组成。这些数据类型确实有预定义的内置函数,允许我们操作数组或对象内的数据。
原始数据类型是可变的;这意味着以后可以修改的数据类型被称为可变的。此外,非原始数据类型是通过引用调用的。让我们通过下面的例子来理解这一点。
let a = [1,2];
let b = a;
b.push(3);
console.log(a)
console.log(b)
输出:
[ 1, 2, 3 ]
[ 1, 2, 3 ]
上例的图像如下所示。
在此示例中,我们创建了一个数组 a
,其中包含两个元素:[1,2]
。由于数组是非原始数据类型,变量 a
不会存储所有数组元素。相反,值 [1,2]
将存储在内存中的另一个位置。在这种情况下,该数组的起始地址,在这种情况下,0x01
,将存储在变量 a
中,如上图所示。由于变量 a
具有存储实际数组元素的地址,因此它将指向该位置。
当我们将变量 a
分配给变量 b
时,我们将存在于 a
中的地址存储到变量 b
中。现在,变量 b
也将指向与变量 a
相同的内存位置 0x011
,因为它们具有相同的内存地址。因此,如果你更改由 b
指向的数组的元素,那么 a
也会受到影响,因为两者都指向相同的位置。
在这里,我们使用变量 b
(例如 b.push(3)
)将一个新元素推送到数组中。现在,变量 b
将从第一个元素 1
开始遍历整个数组,直到最后一个元素 2
。在最后一个元素之后,它将新元素 3
插入到数组中。如果你同时打印变量 a
和 b
,你将看到由于引用,它们都将显示与 [1,2,3]
相同的值。
这被称为通过引用传递,因为我们传递的是内存地址本身而不是值。
JavaScript 编程语言支持按值传递和按引用传递。数字、布尔值、字符串、undefined 和 null 等原始值都是通过值传递的。非原始类型(例如数组、对象和类)通过引用传递。
相关文章
在 Angular 中上传文件
发布时间:2023/04/14 浏览次数:71 分类:Angular
-
本教程演示了如何在 Angular 中上传任何文件。我们还将介绍如何在文件上传时显示进度条,并在上传完成时显示文件上传完成消息。
Angular 中所有 Mat 图标的列表
发布时间:2023/04/14 浏览次数:91 分类:Angular
-
本教程演示了在哪里可以找到 Angular 中所有 Mat 图标的列表以及如何使用它们。
Angular 2 中的复选框双向数据绑定
发布时间:2023/04/14 浏览次数:139 分类:Angular
-
本教程演示了如何一键标记两个复选框。这篇有 Angular 的文章将着眼于执行复选框双向数据绑定的不同方法。
在 AngularJS 中重新加载页面
发布时间:2023/04/14 浏览次数:142 分类:Angular
-
我们可以借助 windows.location.reload 和 reload 方法在 AngularJS 中重新加载页面。
在 AngularJs 中设置 Select From Typescript 的默认选项值
发布时间:2023/04/14 浏览次数:78 分类:Angular
-
本教程提供了在 AngularJs 中从 TypeScript 中设置 HTML 标记选择的默认选项的解释性解决方案。
在 AngularJS 中启用 HTML5 模式
发布时间:2023/04/14 浏览次数:150 分类:Angular
-
本文讨论如何在 AngularJS 应用程序上启用带有深度链接的 HTML5 模式。
在 AngularJs 中加载 spinner
发布时间:2023/04/14 浏览次数:107 分类:Angular
-
我们将介绍如何在请求加载时添加加载 spinner,并在 AngularJs 中加载数据时停止加载器。
在 Angular 中显示和隐藏
发布时间:2023/04/14 浏览次数:78 分类:Angular
-
本教程演示了 Angular 中的显示和隐藏。在开发商业应用程序时,我们需要根据用户角色或条件隐藏一些数据。我们必须根据该应用程序中的条件显示相同的数据。
在 Angular 中下载文件
发布时间:2023/04/14 浏览次数:104 分类:Angular
-
本教程演示了如何在 angular 中下载文件。我们将介绍如何通过单击按钮在 Angular 中下载文件并显示一个示例。