function f(a){
a.x = 1;
console.log(a.x);//1
a = { x: 3 };
console.log(a.x);//3
}
var a = { x: 0 };
f(a);
console.lo(a.x);//1
打印结果:
1
3
1
请问最后一个打印结果为什么是1,第4行声明的是全局变量吗
function f(a){
a.x = 1;
console.log(a.x);//1
a = { x: 3 };
console.log(a.x);//3
}
var a = { x: 0 };
f(a);
console.lo(a.x);//1
打印结果:
1
3
1
请问最后一个打印结果为什么是1,第4行声明的是全局变量吗
JS中函数的参数都是按值传递的,可以理解为是个副本。
重点是a = { x: 3}
这一步操作导致了这个结果。
函数的参数a其实和你声明的全局变量a本身不是同一个东西(参数是一个副本),但是由于a是一个对象,属于引用类型,都是同一个内存地址,也就是他们此时还是相等的。所以a.x = 1
这句代码,等同于修改了原始的a对象。但是你后面的操作a = { x: 3}
, 将对象完全赋值给a这个副本后,那么这个内存地址里就不是原始对象a了,等同于将参数a和原始对象a的引用切断,从这里开始他们便不再相等。所以紧接着打印的a.x为3,是副本a的值。后面再打印的a.x是原始a的值。此时两个a已经完全不相等了。
在函数内对形参对象实例进行“重新赋值”(改变其引用)不会影响到实参,有些语言提供了in,out参数来适用这种场景,js没有提供,但可以使用返回值或加入context参数让上层接收到新对象引用
10 回答11.4k 阅读
5 回答4.9k 阅读✓ 已解决
4 回答3.2k 阅读✓ 已解决
2 回答2.9k 阅读✓ 已解决
3 回答2.5k 阅读✓ 已解决
3 回答2.2k 阅读✓ 已解决
2 回答2.7k 阅读✓ 已解决
整个调用过程如图所示。
另,如果函数 f 没有形参,则所有操作就会是针对全局变量 a 及其所指向的对象;