js闭包总结

  1. 闭包就是一个函数里面嵌套一个函数,里面的函数通过return返回出来。
    2.下面创建了4个闭包函数,每个调用都独立,互不干扰。
var num = new Array();
    for(var i=0; i<4; i++){
        //num[i] = 闭包;//闭包被调用了4次,就会生成4个独立的函数
        //每个函数内部有自己可以访问的个性化(差异)的信息
        num[i] = f1(i);
    }
    function f1(n){
       return function f2(m){
          n=n++;
           m=m++;
            alert(n+m);
        }
    }
  
  num[0](2); //alert(2)
  num[0]=null; //释放内存

二、下面是一个经典例子,闭包中变量的变化。

function fn(){
	var n= 0
	return function(){
		var m = 0;
		console.log(++n,++m)
	}
}
var fn1 = fn()
fn1()   //console 1,1
fn1()   //console 2,1

三、下面3种情况,慢慢体会

for (var i = 0; i<5; i++){
	setTimeout(function(){console.log},100)
}
//会打印5个5


for(var i = 0; i<5; i++){
	(function(i){
		setTimeout(function(){console.log(i)},100)
	}(i))
}
//用闭包,把变量放在上级,就会打印0,1,2,3,4
//直接用let也可以实现这种方法


for(var i = 0; i<5; ++i){
	(function(i){
		setTimeout(function(){console.log(i)},1000*i)
	}(i))
}
//每隔1秒执行一次定时器

四、闭包作为参数传递

var num = 11
var fn1 = function(x){
	if(x>num){
		console.log(x)
	}
}
void function(fn2){
	var num = 100
	fn2(30)
}(fn1)
//console  30
//fn1函数作为参数传递进立即执行函数,fn2(30)把30传递进fn1函数,然后执行fn1函数里面的判断。fn1里面的num作用域取的是全局作用域的num

五、闭包的常见数组按钮写法
某段dom结构如下:在该dom结构中,li在列表的下标分别是0,1,2,3,4.请分别为每个li添加点击事件,输出响应的下标,注意:使用原生的js,且只能添加事件不能添加属性.

<ul id="list">
  <li>qw</li>
  <li>er</li>
  <li>ty</li>
  <li>ui</li>
  <li>ou</li>
</ul>

var lis = document.querySelectorAll('li');
    //闭包实现
    for (var i = 0; i < lis.length; i++) {
      lis[i].onclick = (function (j) {
        return function () {
          console.log(j);
        }
      })(i);
    }
    //forEach实现
    lis.forEach(function (v, i) {
      v.onclick = function () {
        console.log(i);
      }
    })
    //ES6实现
    for(let i=0;i<lis.length;i++){
      lis[i].onclick=function(){
        console.log(i);
      }
    }

最后总结一下闭包的好处与坏处

好处
①保护函数内的变量安全 ,实现封装,防止变量流入其他环境发生命名冲突
②在内存中维持一个变量,可以做缓存(但使用多了同时也是一项缺点,消耗内存)
③匿名自执行函数可以减少内存消耗

坏处
①其中一点上面已经有体现了,就是被引用的私有变量不能被销毁,增大了内存消耗,造成内存泄漏,解决方法是可以在使用完变量后手动为它赋值为null;
②其次由于闭包涉及跨域访问,所以会导致性能损失,我们可以通过把跨作用域变量存储在局部变量中,然后直接访问局部变量,来减轻对执行速度的影响

防抖函数中用闭包,储存一个变量函数

// 防抖
function debounce(fn, wait) {    
    var timeout = null;    
    return function() {        
        if(timeout !== null)   clearTimeout(timeout);        
        timeout = setTimeout(fn, wait);    
    }
}
// 处理函数
function handle2() {    
    console.log("防抖函数"); 
}
// 滚动事件
window.addEventListener('scroll', debounce(handle2, 1000));

节流函数

var throttle = function(func, delay) {            
    var timer = null;            
    return function() {                
        var context = this;               
        var args = arguments;                
        if (!timer) {                    
            timer = setTimeout(function() {                        
                func.apply(context, args);                        
                timer = null;                    
            }, delay);                
        }            
    }        
}
let func = function() {            
    console.log("节流函数");        
}
window.addEventListener('scroll', throttle(func, 1000));

单例模式
意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
主要解决:一个全局使用的类频繁地创建与销毁。

var HeadClass = function () { };
var Head = (function () { // 匿名自执行函数
    var instance; // 声明一个instance对象
    return function () {
        if (instance) { // 如果已存在 则返回instance
            return instance;
        }
        instance = new HeadClass() // 如果不存在 则new一个HeadClass对象
        return instance;
    }
})();
var a = new Head();
var b = new Head();
console.log(a===b) // true

柯里化 currying
function Parent(x,y){
return x+y
}
function curryingParent(x){
return function(y){
return x+y
}
}
curryingParent(1)(2)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端段

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值