1、什么是闭包
是对js作用域特性的一种应用,因为函数内定义的局部变量不能被外部获取,而函数却可以访问到其外部作用域的变量,所以可以在其内部定义一个访问局部变量的方法,并将之输出到外部,return出去,也就是在函数销毁之后通过函数输出的方法来访问局部变量。
2、闭包的作用
先看几个栗子??
for (var i = 0; i < 5; ++i) {
setTimeout(function() {
console.log(i + " ");
}, 100);
}
输出结果为 5 5 5 5 5
原因: js 运行环境为单线程,setTimeout 注册的函数需要等到线程空闲时才能执行,此时 for 循环已经结束,i 值为 5,又因为循环中 setTimeout 接受的参数函数通过闭包访问变量 i,所以 5 个定时输出都是 5。
修改方法:将 setTimeout 放在立即执行函数中,将 i 值作为参数传递给包裹函数,创建新闭包。
for (var i = 0; i < 5; ++i) {
(function(i) {
setTimeout(function() {
console.log(i + " ");
}, 100);
})(i);
}
输出结果为: 0 1 2 3 4
function add() {
var x = 1;
console.log(++x);
}
add(); //执行输出2,
add(); //执行还是输出2,
怎样才能使每次执行有加 1 效果呢?使用闭包
function add() {
var x = 1;
return function() {
console.log(++x);
};
}
var num = add();
num(); //输出2,
num(); //输出3,
num(); //输出4,
1.模仿块级作用域
2.储存变量
3.封装私有变量
3.闭包的应用
function debounce(fn,delay){
let timer = null;
return function(){
let context = this
let args = arguments
clearTimeout(timer)
timer = setTimeout(function(){
fn.apply(context,args)
},delay)
}
}
let flag = 0
function foo(){
flag++
console.log(‘Number of calls:%d‘,flag)
}
document.addEventListener(‘click‘,debounce(foo,1000))
function throttle(fn,delay){
let timer = null;
let startTime = Date.now()
return function(){
let curTime = Date .now()
let remaining = delay - (curTime -startTime)
const context = this
const args = arguments
clearTimeout(timer)
if(remaining<=0){
fn.apply(context,args)
startTime = Date.now();
}else{
timer = setTimeout(fn,remaining)
}
}
}
function xxx(){
console.log(‘1‘)
}
document.addEventListener(‘click‘, throttle(xxx,5000))
setTimeout
function f1(a) {
function f2() {
console.log(a);
}
return f2;
}
var fun = f1(1);
setTimeout(fun,1000);//一秒之后打印出1
封装私有变量
function f1() {
var sum = 0;
var obj = {
inc:function () {
sum++;
return sum;
}
};
return obj;
}
let result = f1();
console.log(result.inc());//1
console.log(result.inc());//2
console.log(result.inc());//3
原文:https://www.cnblogs.com/bbldhf/p/12706828.html