JS闭包
- 下面的代码打印了什么?为什么?
js
function daRio() {
let name = "剑大瑞"
let callMe = function(bilibili) {
return bilibili + name
}
return callMe
}
daRio()("帅哥")
- 当JavaScript引擎在执行代码之前会经历哪三个步骤?
- 创建变量时发生了什么?
- 改造下面的代码,使之输出0 - 9,写出你能想到的所有解法
js
for (var i = 0; i< 10; i++){
setTimeout(() => {
console.log(i);
}, 1000)
}
js
var name = 'Tom';
(function() {
if (typeof name == 'undefined') {
var name = 'Jack';
console.log('Goodbye ' + name);
} else {
console.log('Hello ' + name);
}
})();
js
var data = [];
for (var i = 0; i < 3; i++) {
data[i] = function () {
console.log(i);
};
}
data[0]();
data[1]();
data[2]();
- 何谓自由变量?
- 闭包的弊端?
1、JS引擎在执行代码之前会经历哪三个步骤?

在上面这个过程中其实有三个角色相互配合,分别是Javascript引擎大哥、编译器老二、作用域保姆。
- JS引擎负责整个JS代码的编译及执行
- 编译器负责进行语法分析及代码生成
- 作用域根据一套非常严格的家规(「规则」)收集并维护变量一系列的查询,确定谁有权限访问谁。
2、创建变量时发生了什么?

首先编译器会在当前作用域中声明一个变量(如果之前没有声明过),然后在运行在时JS引擎会在作用域中查找(作用域链查找)该变量,如果能找到就对变量进行赋值。
3、闭包
闭包就是基于JavaScript的**「词法作用域」,当嵌套函数在外部环境执行的过程中通过「作用域链」**访问到包含它的函数作用域中变量所形成的一种现象。并且由于嵌套函数存在对包含函数变量引用的原因,导致外部作用域中的变量无法及时销毁,会占用一定的内存。如果闭包过多,则会影响程序性能。
闭包的另一种定义
如果一个函数引用了自由变量,那么该函数就是一个闭包。何谓自由变量?自由变量是指不属于该函数作用域的变量(所有全局变量都是自由变量,严格来说引用了全局变量的函数都是闭包,但这种闭包并没有什么用,通常情况下我们说的闭包是指函数内部的函数)。
js
// 简单的缓存工具
// 匿名函数创造了一个闭包
const cache = (function() {
const store = {};
return {
get(key) {
return store[key];
},
set(key, val) {
store[key] = val;
}
}
}());
console.log(cache) //{get: ƒ, set: ƒ}
cache.set('a', 1);
cache.get('a'); // 1
闭包的形成条件
- 存在内、外两层函数
- 内层函数对外层函数的局部变量进行了引用
闭包的用途
可以定义一些作用域局限的持久化变量,这些变量可以用来做缓存或者计算的中间量等。
- 模块化
- 柯里化 Currying
闭包的弊端
持久化变量不会被正常释放,持续占用内存空间,很容易造成内存浪费,所以一般需要一些额外手动的清理机制。