作者:灰包蛋啦_199 | 来源:互联网 | 2023-12-14 18:45
本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。
1. 什么是闭包
MDN定义:Closures are functions that refer to independent (free) variables (variables that are used locally, but defined in an enclosing scope). In other words, these functions ‘remember’ the environment in which they were created.
You Don’t Know JS: Closure is when a function is able to remember and access its lexical scope even when that function is executing outside its lexical scope.
我所明白的闭包就是,纵然外部函数已运转终了,内部函数仍能接见外部函数的作用域中的变量。
抓重点: 函数, 作用域。
2. 闭包的运转机制
2.1 词法作用域查找划定规矩
在闭包的运用中,为何我们可以经由过程闭包接见外部函数的作用域中的变量?其一,词法作用域的查找划定规矩是“冒泡”的,即向外层一层层查找,直到全局作用域,所以可以接见外部函数的作用域。其二,函数的作用域是定义时地点的作用域,而不是运转时的作用域。
function foo() {
var a = 1;
function bar() {
console.log(a);
}
return bar;
}
var a = 2;
var baz = foo();
baz(); //1
在上面的代码中,因为bar定义在foo的内部,因而可以向外“冒泡”接见foo的作用域。当运转baz时,a的值为1而不是2,也说清楚明了函数的作用域是定义时的作用域,是静态的。
2.2 渣滓接纳 + 援用
当函数实行终了后,引擎的渣滓接纳机制会开释不再运用的内存空间。因而,当外部函数实行终了时,外部函数的内部作用域理应是该被烧毁的。但是,因为闭包存在对外部函数作用域的援用,因而此作用域依然存在,所以内部函数仍能在外部函数实行完毕以后接见外部函数定义的变量,此之为“记着”。
3. 闭包的运用场景
3.1 私有变量 + 模块
需求:只能经由过程函数供应的要领接见函数内部的变量——隐蔽。只能内部接见——私有。
function bookInfo() {
var book = {
name: "You Don't know JS",
price: 66
};
function getPrice() {
console.log(book.price);
}; function getName() {
console.log(book.name);
}; function setPrice(price) {
book.price = price;
}; return {
getPrice,
getName,
setPrice
};
};
var book = bookInfo();
book.getPrice(); //66
book.getName(); //"You Don't know JS"
book.setPrice(100);
book.getPrice(); //100
在以上的代码中,bookInfo
经由过程返回一个对象,该对象的值是对内部函数的援用,而不是对变量的援用。因而,完成了函数内部变量是隐蔽的(只能经由过程返回的对象要领接见)且私有的(只要函数内部才接见)。
在模块中,返回的变量就被称为模块的大众API
,模块内部的变量只能经由过程这些要领去运用。
3.2 偏函数运用
需求:函数须要先接收一些参数,随后再接收另一些参数的时刻。
比方,当我盘算商品的总价钱时,我想先设定商品的单价,随后依据购置数目算出总的商品价钱。
function partialApply(fn, ...fixedArgs) {
return function (...remainingArgs) {
return fn.apply(this, fixedArgs.concat(remainingArgs));
}
}
function calTotalPrices(price, count) {
console.log(price * count);
}
var pay = partialApply(calPrice, 10);
pay(5);
在上面的代码中,pay
就是在partialApply
的外部接见了partialApply
的内部变量(函数参数)。
4. 为何闭包很主要?参考资料