首页 > 语言 > JavaScript > 正文

JavaScript中最容易混淆的作用域、提升、闭包知识详解(推荐)

2024-05-06 14:52:00
字体:
来源:转载
供稿:网友

一、函数作用域

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

这段代码等价于:

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选