转行前端(JS篇6):一道题教你区分私有变量和全局变量、作用域链

111 阅读3分钟

全局变量和私有变量

#解题思路#:

区分好私有和全局变量,必须给我记住,记不住背下来

在私有作用域中,只有以下两种情况是私有变量

A:声明过的变量(带var/function)

B:形参也是私有变量

剩下的都不是自己私有变量,都需要基于作用域链的机制向上查找

var a=12,
    b=13,
    c=14;
function fn(a){
    console.log(a,b,c)
    var b=c=a=20
    console.log(a,b,c)
}
fn(a)
console.log(a,b,c)


这道题很明显

执行fn(a)(小括号中的是实参:值),会把全局变量a的值12当作实参传递给函数的形参=>fn(12)。
此时fn会形成一个私有作用域:a,b是私有变量,c是全局变量
第1次console.log(a,b,c)   =>(12,undefined,14)注意此时a=12:函数传参,c为全局变量向上查找142次console.log(a,b,c)   =>(202020)
第3次console.log(a,b,c)   =>(121320)此时c为20是因为在函数里面,全局变量被改为20

如果你还没看懂那就好好看看下面整个执行过程把。


机器执行过程:
全局下
变量提升:【var只是声明无定义】var a;var b;var c
         【函数声明加定义】fn=xxx...
接下来代码自上而下执行
执行变量的赋值a=12b=13,c=14
function fn...这一行机器是直接跳过不执行,因为变量提升阶段已经声明和定义好了,所以机器不会重复操作了
接下来执行fn(a)(小括号中的是实参:值)=>执行fn,会把 把全局变量A的值12当作实参传递给函数的形参=>fn(12)。此时fn会形成一个私有作用域:
1、形参赋值a=12
2、变量提升var b
在私有作用域中,只有以下两种情况是私有变量
A:声明过的变量(带var/function)
B:形参也是私有变量
剩下的都不是自己私有变量,都需要基于作用域链的机制向上查找
因此fn(a)里的私有用域里内:ab是私有变量,与外面无关
不过由于a是形参赋值,a会把12传进来,b则是undefined,c是全局变量,向上级window查找是14
输出(12,undefined,14var b=c=a=20 
var b=20
c=20//=>把全局c修改为20
a=20
输出(202020)
fn执行全部
全局下console.loga,b,c)
输出(121320
var ary=[12,23]
function fn(ary){
console.log(ary);  //=>[12,23]
ary[0]=100;
ary=[100];
ary[0]=0;
console.log(ary);  //=>[0]
}

fn(ary);
console.log(ary);   //=>[100,23]

结合了私有/全局,变量提升/形参赋值,作用域,基本类型和引用类型

最好的方式就是自己画图!!!!