函数内局部变量与全局变量的问题
概要:最近在网络上偶然看到的局部与全局变量的问题,发现自己也有点理解困难,便尝试分析下...
🍀问题:
✋如下代码所示:
var foo = {n:1}
(function(foo){
var foo;
console.log(foo.n);
foo.n = 3;
var foo = {n:2};
console.log(foo.n);
})(foo)
console.log(foo.n);
这个函数最终的结果是报错,因为立即执行函数括号前没有分号分隔赋值语句的”}“,导致语法错误。那么,如果确实有分号,语法正确的情况下,这些代码执行后会输出什么呢?往下修改演示代码。
var foo = {n:1};
(function(foo){
var foo;
console.log(foo.n);//1
foo.n = 3;
var foo = {n:2};
console.log(foo.n);//2
})(foo)
console.log(foo.n);//3
//输出结果:
//1
//2
//3
第一次看到结果确实蛮奇怪的,那么接下来分析下造成该输出结果的原因。
🍀分析:
1、先注释部分代码,确认各变量的作用范围
var foo = {n:1};
(function(foo){
// var foo;
console.log(foo.n);//1
// foo.n = 3;
// var foo = {n:2};
// console.log(foo.n);
})(foo)
console.log(foo.n);//1
//输出结果:
//1
//1
这里可以看到立即执行函数在第8行代码接收了全局变量foo = {n:1}
,可以确定第一个输出的foo.n
确实为1。
2、取消部分注释
var foo = {n:1};
(function(foo){
// var foo;
console.log(foo.n);//1
foo.n = 3;
// var foo = {n:2};
console.log(foo.n);//3
})(foo)
console.log(foo.n);//3
//输出结果:
//1
//3
//3
这里可以看到在5行的foo.n=3;
后,7行和10行输出结果都为3,说明foo.n=3;
改变了全局变量
同时7行代码也是访问到了全局变量。注意:由于在取消3行的//var foo;
注释后,输出结果不变,说明var foo;
无法创建绑定为函数内部的局部变量的foo变量。
3、取消全部注释,结果分析
var foo = {n:1};
(function(foo){
var foo;
console.log(foo.n);//1
foo.n = 3;
var foo = {n:2};
console.log(foo.n);//2
})(foo)
console.log(foo.n);//3
//输出结果:
//1
//2
//3
这里可以看到,7行代码输出结果改变了,说明var foo = {n:2};
创建了绑定为函数内局部变量的foo变量,同时赋值该局部变量不影响全局变量,所以第10行代码输出的依旧是在函数未创建局部变量foo前第5行代码修改的全局变量的值:3。
4行代码输出1是立即执行函数()(foo)
接收的全局变量foo = {n:1}
;7行代码输出的是6行代码声明并赋值的局部变量foo = {n:2}
;10行输出的是函数内第5行代码foo.n =3;
修改后的全局变量。
4、增加部分代码以验证分析
var foo = {n:1};
(function(foo){
var foo;
console.log(foo.n);//1
foo.n = 3;
var foo = {n:2};
console.log(foo.n);//2
/*增加的代码*/
foo.n = 4;
console.log(foo.n);//4
})(foo)
console.log(foo.n);//1
//输出结果:
//1
//2
//4
//1
这里输出的结果可以看出:确实,在创建了函数作用域内局部变量foo后,foo.n = 4;
修改的是局部变量,不影响全局变量。
注意:此时可以通过传入window对象来修改全局变量。
🍀分析结束
在存在传入局部作用域的全局变量的情况下,仅在声明同名变量的情况下,无法覆盖传入的全局变量,需要为其赋值才能以局部变量的形式覆盖传入的全局变量。
😉👌
感觉有点小问题。。。
😳💦