一、函数作用域
1.函数作用域
就是作用域在一个“Function”里,属于这个函数的全部变量都可以在整个函数的范围内使用及复用。
function foo(a) {var b = 2;function bar() {// ...}var c = 3;}bar(); // 失败console.log( a, b, c ); // 三个全都失败
上面的“foo”函数内的几个标识符,放到函数外面访问就都会报错。
2.立即执行函数表达式
在任意代码片段外部添加包装函数,可以将内部的变量和函数定义“隐藏”起来,外部作用域无法访问包装函数内部的任何内容。
例如上面的bar、a等几个标识符。这样能够保护变量不被污染。
在写插件的时候经常会用到立即执行函数表达式,为的就是保护里面的变量。
var a = 2;(function foo() {var a = 3;console.log( a ); // 3})();console.log( a ); // 2
“foo”中第一个( )将函数变成表达式,第二个( )执行了这个函数。
有一个专用术语:IIFE,代表立即执行函数表达式(Immediately Invoked Function Expression);
1. 进阶用法是把它们当作函数调用并传递参数进去
(function IIFE( global ) { var a = 3;console.log( a ); // 3console.log( global.a ); // 2})( window );
2. 一种变化的用途是倒置代码的运行顺序,在CMD或AMD项目中被广泛使用。
(function IIFE(factory) {factory( window );})(function def( global ) {var a = 3;console.log( a ); // 3console.log( global.a ); // 2});
二、块作用域
JavaScript不支持块作用域。
for(var i=0; i<10; i++) {console.log( i );}
上面的代码中的“i”相当于下面的
var i;for(i=0; i<10; i++) {console.log( i );}
但也有例外,“try/catch”,catch就是一个块作用域。
try{undefined(); // 执行一个非法操作来强制制造一个异常 } catch(err) {console.log( err ); // 能够正常执行!}console.log( err ); // ReferenceError: err not found
ES6改变了现状,引入了新的let关键字,let关键字可以将变量绑定到所在的任意作用域中(通常是{ .. }内部)。换句话说,let为其声明的变量隐式地了所在的块作用域。
三、提升
函数作用域和块作用域的行为是一样的,可以总结为:任何声明在某个作用域内的变量,都将附属于这个作用域。
1)编译与执行
变量和函数的所有声明都会在任何代码被执行前首先被处理,可以看下面的代码事例。
a = 2;var a;console.log(a);//2
这段代码等价于:
新闻热点
疑难解答
图片精选