1.什么是自由变量?
**自由变量相当于Java中的全局变量,它在外层作用域中声明,但在内层作用域中使用。**在当前作用域中没有定义的变量称为自由变量。
如下所示:其中a就属于自由变量
//自由变量
var a=100;
function fn(){
var b=200;
console.log(a);//这里的a就是一个自由变量
console.log(b);//200
}
fn();//100,200
2.什么是作用域链?
当在Javascript中使用一个变量的时候,首先Javascript引擎会尝试在当前作用域下去寻找该变量,如果没找到,再到它的上层作用域寻找,以此类推直到找到该变量或是已经到了全局作用域。
如果在全局作用域里仍然找不到该变量,它就会在全局范围内隐式声明该变量(非严格模式下)或是直接报错。
说直白一点就是 作用域的集合就是作用域链(子集可以访问父集,父集不能访问子集)
//作用域链
var a=100;
function fn(){
var b=200;
console.log(b);//200
function fn2(){
console.log(a);//自由变量,顺着作用域链向父作用域找
}
fn2();
}
fn();//200,100
从上面的代码可以看到,调用fn2()函数输出a的值时,fn2()作用域中没有a变量的值,此时会顺着作用域链向外面一层作用域中寻找a。外面一层作用域fn()中也没有a的值,再继续顺着作用域链在全局作用域中寻找a的值,最终输出a=100。
3.关于自由变量的取值
在fn函数中,取自由变量x的值时,要到哪个作用域中取?
切记:要到创建fn函数的那个作用域中取,无论fn函数在哪里调用,其实这就是所谓的静态作用域。
//无论fn函数在哪里调用,我们要到创建函数fn的那个作用域中取
var x=10;
function fn(){
console.log(x);
}
function show(f){
var x=20;
function f1(){
f();
};
f1();
}
show(fn);//10,而不是20
fn在全局作用域中被创建,所以要在全局作用域中寻找并输出x的值,为10。