JavaScript中值和引用的区别

761 阅读4分钟

JavaScript中值和引用的区别

在JavaScript中,你可以通过值和引用进行传递。

两者之间的主要区别是,通过值传递发生在分配基元的时候,而通过引用传递发生在分配对象的时候。

让我们在这篇文章中更详细地讨论值和引用。

1.理解基元和对象

JavaScript提供了2类数据类型:基元对象

基元是数字、布尔、字符串、符号以及特殊值nullundefined

// Primitives
const number = 10;
const bool = false;
const str = 'Hello!';
const missingObject = null;
const nothing = undefined;

第二类是对象。特别是普通对象、数组、函数等等--都是对象。

// Objects
const plainObject = {
  prop: 'Value'
};
const array = [1, 5, 6];
const functionObject = (n1, n2) => {
  return n1 + n2;
};

换句话说,任何不是原始值的东西都是一个对象。

2.值

按值传递的简单规则是,JavaScript中所有的原始值都是按值传递的。就这么简单。

按值传递意味着每次你给一个变量赋值时,都会创建一个该值的副本。每一次都是如此。

Values in JavaScript

让我告诉你按值传递是如何体现的。

假设你有两个变量ab :

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

第一条语句let a = 1 定义了一个初始化为数字1 的变量a

第二条语句let b = a 定义了另一个变量b ,并用a 变量的值来初始化它 - 这就是按值传递。更简单地说,数字1 的副本被分配到b

后来,b = b + 2 增加了2 ,变成了3b 变量发生了变化,而这种变化并不影响a 的值。

3.引用

然而,通过引用传递的方式表现得不同。

当创建一个对象时,你会得到该对象的一个引用。如果两个变量持有相同的引用,那么改变对象就会反映在两个变量中。

References in JavaScript

让我们看看下面的代码示例。

let x = [1];
let y = x;
y.push(2);
console.log(x); // [1, 2]
console.log(y); // [1, 2]

第一条语句let x = [1] ,创建了一个数组,定义了一个变量x ,并且用创建的数组的引用初始化了这个变量。

然后,let y = x 定义了一个变量y ,并用存储在x 变量中的引用初始化了y 。这是一个通过引用的传递。

注意:为了简单起见,我说变量持有对对象的引用。但严格地说,JavaScript中的变量持有的值是对对象的引用

4.比较值和比较引用

当你想比较对象时,理解值和引用之间的区别是很重要的。

当使用严格的比较运算符=== ,如果2个拥有数值的变量具有相同的数值,那么它们就是相等的。以下所有的比较都是相等的:

const one = 1;
const oneCopy = 1;
console.log(one === oneCopy); // true
console.log(one === 1);       // true
console.log(one === one);     // true

但是,比较运算符=== 在比较引用时的工作方式不同。2个引用只有在引用完全相同的对象时才是相等的。

ar1ar2持有对不同数组实例的引用:

const ar1 = [1];
const ar2 = [1];
console.log(ar1 === ar2); // false
console.log(ar1 === [1]);  // false
const ar11 = ar1;
console.log(ar1 === ar11); // true
console.log(ar1 === ar1);  // true

ar1 和 引用了相同结构的数组,但是 评估为 ,因为 和 引用了不同的数组对象。ar2 ar1 === ar2 false ar1 ar2

比较运算符只在比较指向同一对象的引用时返回truear1 === ar11ar1 === ar1

5.总结

在JavaScript中,原始类型是作为值传递的:这意味着每次分配一个值时,都会创建一个该值的副本。

另一方面,对象(包括普通对象、数组、函数、类实例)是引用。如果你修改了对象,那么所有引用该对象的变量都会看到这个变化。

比较运算符区分了数值和引用的比较。2个持有引用的变量只有在引用完全相同的对象时才是相等的,但是2个持有值的变量如果只是有2个相同的值,那么它们就是相等的,不管这个值来自哪里:来自一个变量、字面等等。