第五章 作用域与作用域链
1. 作用域
常见的作用域有两种,全局作用域和函数作用域。ES6中新增了块级作用域。
全局作用域中声明的变量与函数可以在代码的任何地方被访问。全局作用域有以下三种情形:
1)全局对象下拥有的属性与方法
window.name;
window.location;
window.top;
……
2)在最外层声明的变量与方法
var foo = function () {}
var str = 'out variable';
var arr = [1, 2, 3];
function bar () {}
3)在非严格模式下,函数作用域中未定义但直接复制的变量与方法(没看懂)
function foo () {
bar = 20;
}
function fn () {
foo();
return bar + 30;
}
fn(); // 50
函数作用域中声明的变量与方法,只能被下层子作用域访问,而不能被其他不相干的作用域访问。
function foo () {
var a = 20;
var b = 30;
}
foo();
function bar () {
return a + b;
}
bar(); // Uncaught ReferenceError
因为作用域的限制,bar中无法访问变量a和b,因此函数执行报Uncaught ReferenceError。
function foo () {
var a = 20;
var b = 30;
function bar () {
return a + b;
}
return bar();
}
foo(); // 50
bar中作用域为foo的自作用域,因此能访问到变量a和b。
块级作用域通过ES6新增的let和const来体现。
function f1 () {
let n = 5;
if (true) {
let n = 10;
}
console.log(n); // 5
}
上面的函数有两个代码块,都声明了变量n,运行后输出5,这表示外层代码块不收内层代码块的影响。如果两次都使用var定义变量n,最后输出的值才是10。
2. 立即执行函数(Immediately Invoked Function Expression, IIFE)
块级作用域出现前,常使用IIFE去模拟块级作用域。
var a = 2;
(function foo () {
var a = 3;
console.log(a); // 3
})();
console.log(a); // 2
由于函数被包含在一对括号内部,因此成为了一个表达式,通过在末尾加上了另外一个括号可以立即执行这个函数。
IIFE另一个皮鞭的进阶用法是把它们当做函数调用并传递参数进去。
var a = 2;
(function IIFE (global) {
var a = 3;
console.log(a); // 3
console.log(global.a); // 2
})(window);
console.log(a); // 2
我们将window对象的引用传递进去,但将参数命名为global,因此在代码风格上对全局对象的引用变得比引用一个没有“全局”字样的变量更加清晰。了解更多块级作用域的知识,请点击这里。
3. 作用域链
关于作用域链的知识,本书讲解不是很详细,我本人也理解的不是很好,回头再补上。
以上是我对JavaScript核心技术开发解密第五章的读书笔记,码字不易,请尊重作者版权,转载注明出处。
By BeLLESS 2018.6.30 15:11