一、基本概念
闭包是指有权访问另一个函数作用域中变量的函数,即在函数内部创建另一个函数。闭包可以从内层函数访问外层函数的作用域,但外层函数却不能访问内层函数的作用域。
function outer() { var name = "Alice"; function inner() { console.log(name); } return inner; } var func = outer(); func(); // 输出 "Alice"
在上述代码中,outer函数返回了inner函数,inner函数可以通过闭包访问到outer函数作用域中的name变量。
二、优点
1、保护变量不受全局污染
闭包可以让某些变量不受全局污染,只有在创建闭包的函数中才能访问。这样可以有效地保护变量不会被非法修改。
function counter() { var count = 0; return function() { console.log(++count); } } var c = counter(); c(); // 输出 1 c(); // 输出 2
在上述代码中,count变量只能在counter函数内部访问,不受全局污染。
2、实现私有变量和函数
闭包可以模拟面向对象中的私有变量和函数,实现数据的封装性和安全性。
function Person() { var name = "Alice"; function getName() { return name; } this.showName = function() { console.log(getName()); } } var p = new Person(); p.showName(); // 输出 "Alice" console.log(p.name); // undefined console.log(p.getName); // undefined
在上述代码中,name变量和getName函数都是私有的,只有通过showName函数才能访问。
3、实现函数式编程
闭包可以用于实现函数式编程,即将函数作为参数传递给另一个函数。
function add(x) { return function(y) { return x + y; } } var add1 = add(1); console.log(add1(2)); // 输出 3 console.log(add1(3)); // 输出 4
在上述代码中,add函数返回一个闭包,用于实现柯里化,从而实现类似函数式编程的效果。
三、缺点
1、内存泄漏
由于闭包会将外部函数的作用域对象保存在内存中,因此如果使用不当可能会导致内存泄漏。
function count() { var arr = []; for(var i = 0; i < 1000000; i++) { arr[i] = function() { console.log(i); }; } return arr; } var arr = count(); // arr中包含1000000个闭包
在上述代码中,count函数返回一个包含1000000个闭包的数组,由于每个闭包都保存了i变量,因此会导致内存泄漏。
2、性能问题
由于闭包会涉及到作用域链查找和内存管理等操作,因此会对性能造成一定的影响。
function func() { var str = ""; for(var i = 0; i < 10000; i++) { str += i; } return function() { console.log(str); } } var f = func(); // f是一个闭包 f();
在上述代码中,func函数返回一个闭包,闭包访问了func函数中的str变量,由于str变量是一个较大的字符串,因此会对性能造成影响。
3、作用域链增长
由于闭包会涉及到作用域链的查找操作,因此频繁地使用闭包可能会导致作用域链过长,从而影响性能。
function func() { var name = "Alice"; return function() { console.log(name); } } var f1 = func(); var f2 = func();
在上述代码中,func函数返回一个闭包,每次调用func函数都会创建一个新的闭包,从而增加作用域链的长度。
原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/272379.html