以上两个代码段相同。函数b是在函数c外部声明的。所以它的作用域绑定在函数外层,内部函数a不会到函数c体内取值,所以返回的是1,而不是2。
很容易犯错的一点是,如果函数A调用函数B,却没考虑到函数B不会引用函数A的内部变量。
1 var b = function() { 2 console.log(a); 3 }; 4 function c(f) { 5 var a = 1; 6 f(); 7 } 8 c(b); //Uncaught ReferenceError: a is not defined 9 10 11 var b = function() { 12 return a; 13 }; 14 function c(f) { 15 var a = 1; 16 return f(); 17 } 18 console.log(c(b)); //Uncaught ReferenceError: a is not defined
上面代码将函数b作为参数,传入函数c。但是,函数b是在函数c体外声明的,作用域绑定外层,因此找不到函数c的内部变量a,导致报错。
同样的,函数体内部声明的变量,作用域绑定在函数体内部。
1 function keith() { 2 var a = 1; 3 4 function rascal() { 5 console.log(a); 6 } 7 return rascal; 8 } 9 10 var a = 2; 11 var f = keith(); 12 f(); //1
上面代码中,函数keith内部声明了rascal变量。rascal作用域绑定在keith上。当我们在keith外部取出rascal执行时,变量a指向的是keith内部的a,而不是keith外部的a。这里涉及到函数另外一个重要的知识点,即在一个函数内部定义另外一个函数,也就是闭包的概念。下次有机会会分享。
总之,函数执行时所在的作用域,是定义时的作用域,而不是调用时所在的作用域。