<返回更多

JS基础入门:闭包详细讲解

2019-05-07    
加入收藏

闭包是函数创建时作用域内所有变量的集合。要使用闭包,需要在另一个函数中创建一个函数,这种函数被称为嵌套函数。内部函数可以访问外部函数作用域中的变量(依靠闭包可以访问外部函数作用域),即使在返回外部函数之后也是如此。每次创建嵌套函数时都会创建闭包。

JS基础入门:闭包详细讲解

 

作用域链

在继续了解闭包之前,首先了解一下JAVAScript中的作用域链。

通常,有两种类型的作用域:

JavaScript中,函数内部的变量在外部是不可见的。但是在块内的变量(if 或 while 之类)是可见的。

var a = 10;
function App(){
 var b = 2;
 console.log(a); // 10
 console.log(b); // 2
}
console.log(b); // ReferenceError: b is not defined
app();

正像我们已知的那样,a 是一个全局变量并且 b 是一个局部变量,它是app函数独有的。

我们无法从局部作用域之外获取局部变量的值。

使用嵌套函数 —— 函数内部的函数

var a = 10;
function app(){
 var b = 2;
 var d = 3;
 function add(){
 var c = a + b;
 }
 return add;
}
var x = app();
console.dir(x);

在这里app是父函数,add函数是子函数。

如果在浏览器中查看控制台,可以在Scopes数组中看到Closure对象。

JS基础入门:闭包详细讲解

 

由于内部函数add访问外部函数变量b 和 d,因此这2个变量将被添加到Closure对象中以供引用。

让我们看看下一个例子:

var a = 10;
var startFunc;
function app(){
 var b = 2;
 function add(){
 var c = a + b;
 console.log(c);
 }
 startFunc = add();
}
app(); // 调用app函数
startFunc; // 上面调用的app函数会将add函数赋值给startFunc并输出c的值

在JavaScript中使用闭包

很多人在编码时会用到闭包,但是不明白用它的原因。 JavaScript没有像其他面向对象语言一样的访问修饰符,例如 private,public,protected。不过我们可以利用函数来保护命名空间免受外部代码使用的影响。

特别是在函数中,**立即执行函数表达式(IIFE)**是在声明之后会立即执行的函数表达式。在声明函数之后,你不需要去调用该函数。

IIFE的语法定义是:

(function(){
 //函数内部的变量和作用域
})();

举个例子:

var studnetEnrollment = (function () {
 //私有变量,任何人都无法改变
 //除了下面声明的函数
 var count = 0;
 var prefix = "S";
 // 返回一个命名函数表达式
 function innerFunc() {
 count = count + 1;
 return prefix + count;
 };
 return innerFunc;
})();
var x = studnetEnrollment(); // S1
console.log(x);
var y = studnetEnrollment(); // S2 
console.log(y);

count和prefix是两个私有变量,任何人都无法进行更改,只能访问内部函数(即代码中的innerFunc)。只有名为闭包的功能才能对此进行访问。

结论

闭包是外部函数中的变量集合,它提供对内部函数作用域的访问以保护全局命名空间。

闭包使开发人员能够编写像面向对象语言那样的干净代码,这些代码不会混淆全局和局部变量的名称。
 

声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>