在JavaScript中,可以按值和按引用传递。
这两种方法的主要区别在于,在赋值原始值(primitive
)时是传递值,而在赋值对象(objects
)时是传递引用。
让我们在这篇文章中更详细地讨论值和引用。
primitive && objects
JavaScript提供了两类数据类型: 基本类型(primitive
)和引用类型(objects
)。
基本类型包括数字、布尔值、字符串、符号和特殊值(null和undefined)。例如:
// 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; };
换句话说,任何不是原始值的东西都是对象。
值传递
按值传递的简单规则是,JavaScript中的所有原始值都是按值传递的。就这么简单。
通过值传递意味着每次给变量赋值时,都会创建该值的一个副本。
假设你有两个变量a和b:
let a = 1; let b = a; b = b + 2; console.log(a); // 1 console.log(b); // 3
第一个语句让a = 1
定义一个初始化为数字1
的变量a。
第二个语句让b = a
定义另一个变量b
,并使用一个变量的值初始化它——这是通过value
传递的。简单点说,把数字1
的一个副本赋给b
。
之后,b = b + 2
增加2
,变成3
。变量b
发生变化,这个变化不影响变量a的值。
引用传递
然而,引用传递的表现方式不同。
当创建一个对象时,你会得到一个对该对象的引用。如果两个变量拥有相同的引用,那么改变对象会反映在两个变量中。
让我们检查下面的代码示例:
let x = [1]; let y = x; y.push(2); console.log(x); // [1, 2] console.log(y); // [1, 2]
第一个语句让x =[1]
创建一个数组,定义一个变量x
,并使用对创建的数组的引用初始化该变量。
然后让y = x
定义一个变量y
,并使用存储在x
变量中的引用初始化y
。这是一个引用传递。
y.push(2)
通过入项2
来改变数组。因为x
和y
变量引用相同的数组,所以这一变化反映在两个变量中。
注意: 为简单起见,我说变量包含对对象的引用。但是严格地说,JavaScript中的变量保存的值是对对象的引用。
使用比较运算符
在比较对象时,理解值和引用之间的差异很重要。
当使用严格比较操作符===
时,如果两个变量的值相同,那么它们就是相等的。下面所有的比较都是相等的:
const one = 1; const oneCopy = 1; console.log(one === oneCopy); // true console.log(one === 1); // true console.log(one === one); // true
one
和oneCopy
的值相同。当两个操作数的长度都为1
时,操作符===
的计算结果为true
,而不管值是从哪里取的。
但是比较操作符===
在比较引用时的工作方式不同。只有当它们引用完全相同的对象时,两个引用才相等。
例如,ar1和ar2引用不同的数组:
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引用不同的数组对象。
比较操作符仅在比较指向同一个对象的引用时返回true: ar1 === ar11
或ar1 === ar1
。
总结
在JavaScript中,基本类型是作为值传递的:这意味着每次赋值时,都会创建一个值的副本。
另一方面,对象(包括普通对象、数组、函数、类实例)是引用。如果您修改了该对象,那么所有引用该对象的变量都将看到更改。
比较运算符区分比较值和引用。只有引用了完全相同的对象时,两个引用的变量才相等,但如果两个变量的值是相同的,那么它们的值就是相等的,而不管值来自哪个地方。