1、什么是做用域javascript
简单来讲,做用域就是定义变量和函数的区域,变量和函数在该区域能够被访问。java
须要注意的有三点:闭包
访问变量时,应从变量定义的做用域沿着做用域链向上查找函数
var name = '小明'; function fn1() { var name = "小红"; function fn2() { console.log('方法fn2中打印name:' + name); // 方法fn2中打印name:小红 } fn2(); } fn1();
函数做用域只有函数才能建立,而且在该做用域在函数定义时就已经肯定了code
// 例子1 var name1 = '小明'; function fn1() { console.log('方法fn1中打印name1:' + name1); // 方法fn1中打印name1:小明 } function fn2() { var name1 = '小红'; fn1(); console.log('方法fn2中打印name1:' + name1); // 方法fn1中打印name2:小红 } fn2(); // 例子2 var name2 = '小明'; function fn3() { var name2 = '小红'; return function() { console.log('闭包函数中打印name2:' + name2); // 闭包函数中打印name2:小红 } } fn3(); // 例子3 var name2 = '小明'; function fn3() { var name2 = '小红'; fn4 = function() { console.log('闭包函数中打印name2:' + name2); // 闭包函数中打印name2:小红 } } fn3(); // 必须执行fn3方法,不然函数做用域中的js代码不会被预解析和执行(Uncaught ReferenceError: fn4 is not defined) fn4();
JavaScript只有全局做用域和函数做用域(或者说局部做用域)。ES5是不存在块级做用域的(例如 if 和 for 体现了没有块级做用域),ES6的出现 提供了两个定义变量的方式 let/const ,才有了块级做用域。ip
// 例子1 if (true) { var name1 = "小明"; } console.log(name1); // 小明 (name1能够被打印说明name1为全局的,不存在块级做用域) // 例子2 if (true) { const name2 = "小明"; } console.log(name2); // Uncaught ReferenceError: name2 is not defined
2、做用域链作用域
了解了做用域后,做用域链就好说了,那么什么是做用域链呢?通俗点讲,当你声明一个函数时,函数做用域一级一级向上包裹起来,这就是做用域链。io
须要注意的有两点:console