js-闭包(封装私有变量,创建模块,函数柯里化接收多个参数转换为接收单一参数,实现迭代器-遍历数组与对象)
1.前言
闭包(Closure)是JavaScript中的一个重要概念,它是指有权访问另一个函数作用域中的变量的函数。简单来说,闭包就是一个函数,这个函数能够记住并访问其词法作用域,即使这个函数在其词法作用域之外执行。
2.使用场景
2.1工厂函数
闭包可以用来创建工厂函数,工厂函数是一种返回函数的函数。
-
是一个函数。
-
用来创建对象。
function makeAdder(x) {
return function(y) {
return x + y;
};
}
const add5 = makeAdder(5);
console.log(add5(10)); // 15
2.2 模块模式
闭包可以用来实现模块模式,模块模式是一种将相关函数和变量封装在一起的机制,可以用来组织代码,防止全局命名空间的污染。
const myModule = (function() {
let privateVariable = 'I am private';
function privateFunction() {
console.log('I am private');
}
return {
publicMethod: function() {
console.log('I am public');
}
};
})();
myModule.publicMethod(); // I am public
// myModule.privateVariable; // ReferenceError: privateVariable is not defined
// myModule.privateFunction(); // ReferenceError: privateFunction is not defined
2.3 迭代器
闭包可以用来实现迭代器,迭代器是一种可以遍历集合(如数组或对象)的机制。
function createIterator(arr) {
let index = 0;
return {
next: function() {
if (index < arr.length) {
return { value: arr[index++], done: false };
} else {
return { done: true };
}
}
};
}
const iterator = createIterator([1, 2, 3]);
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { done: true }
2.4.实现函数柯里化
闭包可以用来实现函数柯里化,函数柯里化是一种将接受多个参数的函数转换成接受一个单一参数(最初函数的第一个参数)的函数,并返回接受余下的参数且返回结果的新函数的技术。
function curry(fn) {
return function curried(...args) {
if (args.length >= fn.length) {
return fn.apply(this, args);
} else {
return function(...args2) {
return curried.apply(this, args.concat(args2));
};
}
};
}
function sum(a, b, c) {
return a + b + c;
}
const curriedSum = curry(sum);
console.log(curriedSum(1)(2)(3)); // 6
3.作用于注意
闭包可以保留被定义时的作用域,闭包内部可以访问外部函数的局部变量 ,即使外部函数已经执行完毕。
闭包会让函数内部的变量在后续函数执行后继续存于内存中,直到没有任何的引用指向闭包,不注意管理闭包可能会造成内存泄漏。
闭包可能会导致内存泄漏(注意是可能)