#js
js
// items 被迭代的数组 返回用于迭代的next函数
function createIterator(items) {
let i = 0;
function next() {
// 如果达到数组长度,则已经完成迭代
let done = i >= items.length;
// 达到数组长度返回undefined,否则返回下一个值
let value = !done ? items[i++] : undefined;
return {
done: done,
value: value
};
}
return { next };
}
const iterator = createIterator([1,2]);
iterator.next(); // "{ value: 1, done: false }"
iterator.next(); // "{ value: 2, done: false }"
iterator.next(); // "{ value: 3, done: true }"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
这一例子中可以说 next()
函数 和 i
构成了闭包,同时也产生了副作用:每执行一次 next()
i
就会加 1。
闭包的特性:
闭包让你可以在一个内层函数中访问到其外层函数的作用域 函数嵌套函数 延长变量的生命周期 在内存中维持一个变量 一般函数的词法环境在函数返回后就被销毁,但是闭包会保存对创建时所在词法环境的引用,即便创建时所在的执行上下文被销毁,但创建时所在词法环境依然存在,以达到延长变量的生命周期的目的
闭包形成的条件:
函数的嵌套 内部函数引用外部函数的局部变量,延长外部函数的变量生命周期 闭包缺点:会导致函数的变量一直保存在自己内存中,过多的闭包可能会导致内存泄漏
闭包应用场景
闭包的两个场景,闭包的两大作用:保存 / 保护。 在开发中,其实我们随处可见闭包的身影,大部分前端 JavaScript 代码都是 “事件驱动” 的,即一个事件绑定的回调方法;发送 ajax 请求成功 | 失败的回调;setTimeout 的延时回调;或者一个函数内部返回另一个匿名函数,这些都是闭包的应用。