JS之闭包与回调


JS之闭包与回调

闭包与回调==》JS高级


一、前提

在学好前提下,再来学习闭包与回调

闭包的前提是预编译和作用域
回调的前提是作用域、函数与函数执行

二、闭包

1.什么是闭包?

闭包是面向对象私有化的
一个函数被系统创建出来就是一个闭包
一个函数与环境(作用域)的相互结合
闭包的好处是能给我们带来集成性和封装性

图片如下(示例):
请添加图片描述

代码如下(示例):

      function test(){//是一个闭包
         const a = 1;
         function fn(){// 是一个闭包  可以调用外部的局部变量
             console.log(a)
         }
         fn()
      }
      test()

     

判断这个是不是闭包

 
         function test(){
            var b = 222
            a(b)
         }
         function a(b){
           console.log(b);
         }
         test()
        // 不是
        // 因为 在a()里面只能读取test()里面b的值 ,再添加一个则读取不了,那想读取无数的值呢,这肯定是不行的
        // 列:
        function test(){
             var b = 222
             var c = 333
              a(b)
         }
        function a(b){
           console.log(b);
            console.log(c)
         }
         test()

出一个简单的小题 加减乘除


        // // 第一种方法
        // function computer(){
        //     function add(a,b)
        //     {
        //         return a + b
        //     }
        //     function sbt(a,b)
        //     {
        //         return Math.abs(a - b) 
        //     }
        //     function mlt(a,b)
        //     {
        //         return a * b
        //     }
        //     function dvs(a,b)
        //     {
        //         return a / b
        //     }
        //     // 方法
        //     // 1.
        //     // computer.do = function(type,a,b) 
        //     // {
        //     //     switch(type){
        //     //         case 'add':
        //     //             return add(a,b)
        //     //         case 'sbt':
        //     //             return sbt(a,b)
        //     //         case 'mlt':
        //     //             return mlt(a,b)
        //     //         case 'dvs':
        //     //             return dvs(a,b)
        //     //         default:
        //     //             break;
        //     //     }
        //     // }
        //     // 2,跟1效果是一样的
        //     return function(type,a,b) 
        //      {
        //         switch(type){
        //             case 'add':
        //                 return add(a,b)
        //             case 'sbt':
        //                 return sbt(a,b)
        //             case 'mlt':
        //                 return mlt(a,b)
        //             case 'dvs':
        //                 return dvs(a,b)
        //             default:
        //                 break;
        //         }
        //     }
        // }
        // //     1.
        // //     computer()
        // //    var ret =  computer.do('add', 100,200)
        // //    console.log(ret)
        // //     2,
        // // 注意需要大写
        // Do = computer()
        // const res = Do('add', 100,200)
        // console.log(res)
        
    //    第二种写法  比较简便 以对象的形式
    //  function computer(){
    //         computer.add = function(a,b)
    //         {
    //             return a + b
    //         }
    //         computer.sbt = function(a,b)
    //         {
    //             return Math.abs(a - b) 
    //         }
    //         computer.mlt = function(a,b)
    //         {
    //             return a * b
    //         }
    //         computer.dvs = function(a,b)
    //         {
    //             return a / b
    //         }
    //         return function(type,a,b){
    //             return  computer[type](a,b)
    //         }
    //     }
    //     Do = computer()
    //     const res = Do('sbt', 100,200)
    //     console.log(res)
        // 可以再简化一下
        function computer(type,c,d){
            computer.add = function(a,b)
            {
                return a + b
            }
            computer.sbt = function(a,b)
            {
                return Math.abs(a - b) 
            }
            computer.mlt = function(a,b)
            {
                return a * b
            }
            computer.dvs = function(a,b)
            {
                return a / b
            }
            return  computer[type](c,d)
        }
        const res = computer('add', 100,200)
        console.log(res)

2.关于闭包的相关问题

这个是一个点击事件

代码如下(示例):

请添加图片描述

问题是缺少闭包,导致最后点击的小li结果都是3(即3 3 3)(他们的总长度是3)(想要的效果是每个小li对应每一个序号)
原因是点击事件并不是作用域,别把绑定事件当成作用域,绑定事件处理函数(这个函数会执行外部的变量)而不是绑定事件直接执行函数
所有在当for都循环完毕,i=3的时候,才能触发绑定事件,那怎么解决呢?
那就是添加立即执行函数(即闭包)

请添加图片描述

创建了函数时,当i=0时,执行立即执行函数(function(i){}) 此时ii=0 以此类推 i= 1 ii =1; i=2 ii=2
函数里面的括号中的参数是充当临时局部变量(即ii会随着i的变化而变化而不是i循环到最后了ii再执行)
最后的结果是 0 1 2

三、回调

1.什么是回调?

回调的大致意思是:主函数里面的参数是回调函数(即回调函数相当于主函数的参数),主函数执行完毕,再执行回调函数(主函数的事先干完,回头再调用传进来的那个函数。)
这个过程就是回调

代码如下(示例):

//定义主函数,回调函数作为参数
function a(callback){
  callback()
  console.log('主函数')
}
//定义回调函数      定时器是异步函数
fuction b(){
  setTimeout("console.log('我是回调函数')", 3000);//模仿耗时操作  
}
//调用主函数,将函数B传进去
a(b)

//输出结果
主函数
我是回调函数


     //  主函数
         function count(count,callback){
             var count1 = count + 1
             var count2 = count + 100
             callback && callback(count2)
            //  console.log(count1)
            return count1
         }
            // 这个是回调函数
         var count3 = count(1,function(count2){
             console.log(count2)
         })
         console.log(count3)


  

2.举个栗子

        // 加减乘除
        function computer(callback){
            return function(a,b,type){//这个是一个闭包
                let result = null
                switch(type){
                    case '+':
                    result = a + b
                    break;
                    case '-':
                    result = a - b
                    break;
                    case '*':
                    result = a * b
                    break;
                    case '/':
                    result = a / b
                    break;
                    default:
                        break;
                }
               callback && callback(a,b,type,result)
            }
        }
        var test = computer(function(a,b,type,result){
             console.log(`${a} ${type} ${b} = ${result}`)
        })
        test(1,2, '+')
        test(100,20, '-')
        

3.验证回调函数

         function test(validator){
            return function(a,b,type){//这个是一个闭包
                
                var {isError, errorMsg } = validator(a,b)
                if(isError){
                    // throw new Error(error); 这个是创建错误,创造一个错误类型抛出;
                    throw new Error(errorMsg)
                }

                switch(type){
                    case '+':
                    return  a + b
                    case '-':
                    return  a - b
                    case '*':
                    return  a * b
                    case '/':
                    return  a / b
                    default:
                        break;
                }
            }
        }
        var comp = test(validator)
        console.log(comp(100,2,'+'))

        function validator(a,b){

            if(a > 50 || b > 30){
                return {
                    isError:true,
                    errorMsg:'a必须小于等于50,并且b小于等于30'
                }
            }
            return{
                isError:false,
                errorMsg:'ok'
            }
        }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值