JS中全局变量作为函数实参传入的问题

JS中全局变量作为函数实参传入的问题

昨天面试时,被问到了以下的JS代码问题,对比两种情况的输出思考为什么会是这样的结果

第一种情况
var a=[1,2,3];
function foo(a){
    a=[4,5,6];
}
foo(a);
console.log(a); // [1,2,3]
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
第二种情况
var a=[1,2,3];
function foo(a){
    a.push(4);
}
foo(a);
console.log(a); // [1,2,3,4]
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

    被问的时候也是蒙圈的,回来仔细查了相关资料,总结一下,希望也能帮助到你理解这个问题。

    看以上两种情况,当全局变量作为函数的实参传入函数之后被重新赋值,然而,执行完函数之后全局变量并没有发生改变,这是为什么?

    JS高级程序设计第三版70页有阐述。加上自己的理解总结如下:

    原本的b=a有两种赋值方式,一种是按值,另一种是按引用。
    ECMAScript中所有的参数传递都是按值传递的,也就是说把函数外部的值复制给函数内部的参数,无论是基本类型还是对象类型,实参和形参都会指向不同的内存地址,并且作用域不同,形参的作用域仅仅在函数体内。
    我们看如下代码:

var a=[1,2,3],
var b=1;
function foo(a,b){
    a=[4,5,6];
    b=2;
}
foo(a,b);
console.log(a); // [1,2,3]
console.log(b); //1;
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

    我们看到全局变量a和b,被作为实参传给形参后,函数体内对变量a、b进行了重新的赋值,但是并没有改变全局变量a、b的值,即说明函数体内的a、b赋值都是对形参的赋值,形参与在函数中声明的变量一样有着相同的性质。

但是有一种情况比较特殊,但是不会违背参数按值传递的规律。看如下代码:

var a=[1,2,3];
function foo(a){
    a.push(4); //调用引用类型方法,改变了形参a,也改变了全局变量a
    console.log(a); // [1,2,3,4] 此时的a是形参变量的值
    a=[5,6,7];      // 形参重新赋值不会改变全局变量a
    console.log(a); // [5,6,7] 形参变量a
};
foo(a);
console.log(a); // [1,2,3,4]
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

再来看如下代码:

var a=[1,2,3];
function foo(a){
    a=[5,6,7]; // 形参a被重新赋值,不会改变全局a
    a.push(4); // 此时只改变了形参a,不会改变全局a
    console.log(a); // [5,6,7,4]
};
foo(a);
console.log(a); // [1,2,3]
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

    对引用数据类型,会发现在函数里,形参被赋值之前,对形参调用引用数据类型的属性(或方法)时,不仅会改变形参,还会改变全局变量。这大概是同名形参和全局变量的一种对应吧,通俗解释一下就是只有当你在函数里被重新赋值之后,你才是独立的。而在这之前我们是穿一条裤子的,属性和方法的调用会同时改变我们。
希望对你有帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值