沙箱、柯里化与函数的自执行以及函数的节流与防抖

134 阅读3分钟

沙箱

什么是沙箱模式

利用了 函数内 间接的返回了一个函数

外部函数返回了一个对象 ,这个对象内书写了多个函数.

        function outer(){
            //1.放置一些外部函数的变量
            let a = 0
            const obj = {
                //2.放置若干函数
                getA:function(){
                    return a
                },
                setA:function(Val){
                    a = Val
                }
            }

            //3.将对象返回到函数外
            return obj
        }


        const res = outer()

        //得到函数内部对象,这个对象内部有多个操作函数
        let oa = res.getA()

        //得到函数内部私有变量a
        console.log(oa)

案例来演示

需求: 创造一个输入框,当我点击加号按钮时,输入框中的数字会自加一,点击减号按钮时会自减一

        //获取输入框以及加减按钮
        const add1 = document.querySelector('.add1')
        const inp1 = document.querySelector('.inp1')
        const sub1 = document.querySelector('.sub1')


        //正常方法

         let count = 1
         add1.onclick = function(){
             //减少
             count--
             inp1.value = count
         }
         sub1.onclick = function(){
             //增加
             count++
             inp1.value = count
         }
        
        
        //沙箱写法

        function outter(){
            let count = 1
            return {
                getCount(){
                    return count
                },
                setCount (Val){
                    count = Val
                }
            }
        }

        const res = outter()
        add1.onclick = function(){
            let num = res.getCount()
            res.setCount(num - 1)
            inp1.value = res.getCount()
        }
        sub1.onclick = function(){
            let num = res.getCount()
            res.setCount(num + 1)
            inp1.value = res.getCount()
        }
        

函数的柯里化

什么是函数的柯里化

一个函数接收多个参数能够完成功能, 柯里化函数就是这一个函数拆分为两个函数, 每个函数都只接收一个参数,然后完成的功能相同

案例:

需求:使用正则完成一个文本匹配

普通版

         const reg = /^\w{6,12}$/
         const str = '12345'
         console.log(reg.test(str)

弊端: 只能检测一种文本,若想检测多种文本则需要创建多个正则.

优化版:

        function testStr(fnReg,fnStr) {
            const reg = fnReg
            const str = fnStr
            console.log(reg.test(str))
        }
        testStr(/^\w{6,12}$/,'12345')

优点: 检测多种文本时无需创建多个正则

弊端:每次调用函数都需要传递两个参数,若两个文本需要检测相同的正则,需要将正则传递两次

柯里化版

        //最外层函数,负责接收正则
        function fn(fnReg){
            //内层函数,负责接收字符串,并完成正则验证
           return function(fnStr){
            console.log(fnReg.test(fnStr))
            //将校验结果返回出去给外部代码使用
            return fnReg.test(fnStr)
           } 
        }
        const testNum = fn(/^\d{6,12}$/)
        testNum('1234')
        testNum('abcd')
        testNum('123456')

优点:若两个文本需要检测的正则类型的相同,无需多次传递正则.

函数的自执行

什么是函数的自执行

函数的自执行即定义和调用合为一体。 我们创建了一个匿名的函数,并立即执行它,由于外部无法引用它内部的变量,因此在执行完后很快就会被释放,关键是这种机制不会污染全局对象

语法:(function fn(形参){})(实参)

案例

(function fn(name){console('我是自己执行的函数名字叫做',name)})('自执行函数')

函数的节流与防抖

节流

什么是函数的节流

事件在执行时,第一次开始执行时,在结束之前或者在指定时间之前,无法触发下一次,除非等到第一次执行结束或者指定时间

        //获取元素
        const inp = document.querySelector('.inp')
         inp.oninput = function (){
            console.log(this.value)
         }
         
         
        //基础版
        
        //创建一个开光变量控制程序是否执行
         let flag = true
         
         inp.oninput = function(){

            if(flag === false) return

            flag = false

            setTimeout(() => {

                flag = true

                console.log(this.value)

            },300)
         }
         
         
         //优化版 (自执行版)       
         let flag = true

        inp.oninput = (function (flag) {
            //当前这个函数会立即执行然后返回f一个函数给到inp.oninput
            return function () {
                if (flag === false) return
                //使用 flag 的时候会先在当前作用域找。没找到。然后去上层作用城(自执行函数内)找,在这里找到了形参flag,初始值为true
                flag = false
                setTimeout(() => {
                    flag = true
                    console.log(this.value)
                }, 300)
            }
        })(true)

防抖

什么是函数防抖

事件在开始执行时 , 如果快速触发了第二次,那么第二次会取代第一次,只执行最后一次.

        //基础版
        
       let timer = 0
        inp.oninput = function (){
            clearInterval(timer)
            timer = setTimeout(() => {
                console.log(this.value)
            }, 300);
        }

        //优化版(自执行版)
        
        inp.oninput = (function (timer) {
            return function () {
                clearInterval(timer)
                timer = setTimeout(() => {
                    console.log(this.value)
                }, 300);
            }
        }
        )(0)