2

JavaScript 原始值与引用的区别

 1 year ago
source link: https://www.myfreax.com/javascript-primitive-vs-reference-values/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
JavaScript 原始值与引用的区别

JavaScript 原始值 vs 引用

在本教程中,您将了解 JavaScript 中两种不同类型的值,分别是原始值和引用值。

JavaScript 有两种不同类型的值:

原始值是原子数据,而引用值是可能包含多个值的对象。

栈和堆内存

当您声明变量时,JavaScript 引擎会在两个内存位置为它们分配内存:堆栈 Stack 和堆 heap。

静态数据是在编译时大小固定的数据。静态数据包括:

由于静态数据的大小是不变的,JavaScript 引擎会为静态数据分配固定大小的内存空间,并将其存储在栈。

例如,下面语句声明两个变量并将它们的值初始化为字符串和数字:

let name = 'John'; 
let age = 25;

因为 nameage 是原始值,JavaScript 引擎将这些变量存储在堆栈中,如下图所示:

JavaScript-stack-memory.webpJavaScript 栈内存

请注意,字符串在许多编程语言是对象,包括 Java 和 C#。然而,字符串是 JavaScript 的原始值。

与堆栈不同,JavaScript 将对象和函数存储在堆。JavaScript 引擎不会为这些对象分配固定数量的内存。相反,它会根据需要分配更多空间。

以下示例定义了 nameageperson 变量:

let name = 'John';
let age = 25;

let person = {
  name: 'John',
  age: 25,
};

在内部,JavaScript 引擎分配内存如下图所示:

JavaScript-heap-memory.webp

JavaScript 堆 内存

在此图中,JavaScript 在堆栈上为三个变量、agename 以及 person 分配内存。

JavaScript 引擎在堆内存上创建一个新对象。此外,它将堆栈内存中的 person 变量链接到堆内存中的对象。因此,我们说 person 变量是对象的引用。

引用值允许您随时添加、更改或删除属性。例如:

let person = {
  name: 'John',
  age: 25,
};

// 添加 ssn 属性
person.ssn = '123-45-6789';

// 修改 name 属性
person.name = 'John Doe';

// 删除 age 属性
delete person.age;


console.log(person);
{ name: 'John Doe', ssn: '123-45-6789' }

与引用值不同,原始值不能具有属性。这意味着您不能将属性添加到原始值。

但 JavaScript 允许您将属性添加到原始值。然而,它不会产生任何效果。

let name = 'John';
name.alias = 'Knight';

console.log(name.alias); // undefined

在此示例中,我们将 alias 属性添加到 name 原始值。但是当我们通过原始值 name 访问 alias 属性时,它返回 undefined

当您将一个变量的原始值分配给另一个变量时,JavaScript 引擎会创建值的副本并将其分配给变量。例如:

let age = 25; 
let newAge = age;

在这个例子中:

  • 首先,声明一个新变量 age 并用值 25 初始化它。
  • 其次,声明另一个变量 newAge 并将 newAge 变量的值分配给 age

在幕后,JavaScript 引擎创建原始值的副本 25 并将其分配给 newAge 变量。下图说明了赋值后的栈内存。

JavaScript-copy-a-primitive-value.webpJavaScript 复制原始值

在堆栈内存中,newAgeage 是单独的变量。如果你改变一个变量的值,它不会影响另一个。

let age = 25;
let newAge = age;

newAge = newAge + 1;
console.log(age, newAge);

JavaScript-change-a-primitive-value.webpJavaScript 改变原始值

当您将一个变量的引用值赋给另一个变量时,JavaScript 引擎会创建一个引用,以便两个变量都引用堆内存中的同一个对象。

这意味着如果你改变一个变量,它会影响另一个。例如:

let age = 25;
let newAge = age;

newAge = newAge + 1;
console.log(age, newAge);

首先,声明一个 person 变量并用一个具有两个属性 nameage 的对象初始化它的值。

第二,将 person 变量赋值给 member 变量。在内存中,两个变量都引用同一个对象,如下图所示:

JavaScript-copy-a-reference-value.webp

JavaScript 复制引用值

第三、通过 member 变量改变 age 对象的属性:

JavaScript-change-a-reference-value.svg

JavaScript 改变引用值

由于 personmember 变量都引用同一个对象,因此通过 member 变量修改对象也会反映在 person 变量中。

  • Javascript 有两种类型的值:原始值和引用值。
  • 您可以向引用值添加、更改或删除属性,而不能对原始值执行此操作。
  • 将原始值从一个变量复制到另一个变量会创建一个单独的值副本。这意味着改变一个变量的值不会影响另一个。
  • 将引用从一个变量赋值到另一个变量会创建一个引用,以便两个变量引用同一对象。这意味着通过一个变量修改对象后会反映在另一个变量中。

微信公众号

支付宝打赏

myfreax 淘宝打赏

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK