JavaScript 是按引用传递还是按值传递的语言?

对于刚刚入门的新手来说,估计都很迷糊 js 的值传递和引用传递,js 不像 C 语言、rust语言等底层语言,会明确一个变量的传递是穿引用,还是传值。

基本规则

JavaScript 是严格按值传递的!!!

基本类型(number, string等)是按值传递的,但对于对象( object ),变量的值是引用。因此,当您传递对象并更改其成员时,这些更改将保留在函数外部。这使它看起来像是按引用传递。但是,如果你真的更改了对象变量的值,你会看到更改不会对函数外部生效,证明它确实是按值传递的。

看个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function changeValue(x) {
x = { props: "bar" };
console.log("改变值: " + x.props);
}

function changeProps(x) {
x.props = "bar";
console.log("改变对象属性: " + x.props);
}

var x = { props: "foo" };

console.log("改变值之前: " + x.props);
changeValue(x);
console.log("改变值之后: " + x.props);

console.log("改变对象属性之前: " + x.props);
changeProps(x);
console.log("改变对象属性之后: " + x.props);

输出

1
2
3
4
5
6
7
改变值之前: foo
改变值: bar
改变值之后: foo

改变对象属性之前: foo
改变对象属性: bar
改变对象属性之后: bar

可以明显看到直接对 x 进行赋值改变,并未影响到函数外面的变量,但是如果直接改变对象的属性,确实对函数体外的变量进行了修改。

个人理解

对于对象 object 这种数据类型,js 内部规则会传递一个值的引用给函数体,如果对引用进行修改,那么会影响到函数体外部,如果对变量直接进行赋值修改,不会影响到函数体外部。

此问题在 stack overflow 上有大量讨论,有兴趣可以阅读 https://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass-by-value-language

本文由 linx(544819896@qq.com) 创作,采用 CC BY 4.0 CN协议 进行许可。 可自由转载、引用,但需署名作者且注明文章出处。本文链接为: https://blog.jijian.link/2023-11-20/javascript-reference-or-value/

如果您觉得文章不错,可以点击文章中的广告支持一下!