JavaScript作用域及作用域链
程序员文章站
2024-02-17 16:31:46
...
只有函数可以制造作用域结构,那么只要是代码,就至少有一个作用域,即全局作用域,
凡是代码中有函数的,那么这个函数就构成另一个作用域,如果函数中还有函数,
那么在这个函数中就又可以诞生一个作用域。
将这样的所有的作用域列出来,可以有一个结构:函数内指向函数外的链式结构。就称为作用域链
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
</body>
<script>
var a = 3;
function f1(){
function f2(){
function f3(){
console.log(a);
}
}
}
</script>
</html>
我们看上面的JS代码,函数里面又写了几个函数,然后我们打印一下试试,看结果:
这个打印出了是没有的,怎么回事,我们这段代码,说了,函数声明了,是不是得调用了啊,我们调用一下试试,我们看这样函数怎么调用:
<script>
var a = 3;
function f1(){
function f2(){
function f3(){
console.log(a);
}
f3();
}
f2();
}
f1();
</script>
</html>
看这个调用代码,直接调用 f1(); ,那虽然说调用了,但是 f1 函数里面什么都没有啊,只有 f2 ,只能是在调用 f2 ,那么在看 f2 ,也是什么都没有,只有 f3 ,那就只能在调用 f3 了,f3 里面才有打印,打印的就是我们声明的变量赋值,所以才出现了这样的函数调用。
那么这时就有一个问题了,我这个 a ,既没有在 f3 里面声明,也没有在 f2 里面声明,更没有在 f1 里面声明,就只是在全局作用域中声明了一个变量a,在局部作用域中是没有的
那我们在看:
<script>
var a = 3;
function f1(){
function f2(){
function f3(){
var a = 4;
console.log(a);
}
f3();
}
f2();
}
f1();
</script>
</html>
我们看这次直接在 f3 里面声明变量,看结果是 4 还是 3 呢:
我们在看几个:
下面是在f2,里面声明:
<script>
var a = 3;
function f1(){
function f2(){
var a = 5;
function f3(){
// var a = 4;
console.log(a);
}
f3();
}
f2();
}
f1();
</script>
</html>
再从 f1 里面声明:
<script>
var a = 3;
function f1(){
var a = 6;
function f2(){
// var a = 5;
function f3(){
// var a = 4;
console.log(a);
}
f3();
}
f2();
}
f1();
</script>
</html>
如果我们再把a = 6,注释掉了,在看呢:
<script>
var a = 3;
function f1(){
// var a = 6;
function f2(){
// var a = 5;
function f3(){
// var a = 4;
console.log(a);
}
f3();
}
f2();
}
f1();
</script>
</html>
其实结果就还是3了,就是我们之前定义的变量3:
其实细心的可能就会发现了,这个 a ,是不像下面的箭头一样,从下向上找啊:
当函数中使用某个变量时,优先在自己的作用域中查找
如果找不到,就会向上一层作用域查找,如果找不到继续向上一层查找,直到全局作用域
如果还找不到就直接报错
这就是: 作用域链