对全局变量说no!:js函数的高级用法-缓存参数

866 阅读2分钟

函数参数缓存

我们在使用js编程的时候,可能会遇到这种场景,一个任务可能分两部分完成,后一个任务依赖前一个任务,这个时候,我们可能会把依赖数据缓存到全局变量中,而另一个任务去取全局变量的任务,有了js函数的灵活性,基本上上面使用全局变量的情况可以完全清除。 我们这里有两个按钮,按钮1与按钮2,按钮1的设置的内容被按钮2依赖,面对这种两个回调函数的依赖,之前我们只能使用两个函数的外部作用域去缓存x,y,z:

let btn1 = document.querySelector('#btn1');
let btn2 = document.querySelector('#btn2');
var x,y,z;//外部缓存共享变量
btn1.addEventListener('click',function(e){
    x = 1;
    y = 2;
    z = 3;
});
btn2.addEventListener('click',function(e){
    // 使用btn1设置或获取的x,y,z数据来做btn2的任务
    console.log(x,y,z)
})

这种操作会完全的依赖全局变量,而且x,y,z只是在这两个按钮之间使用,有的朋友说使用一个对象来缓存,但是无论怎么样,你都需要在外层作用定义一个变量。 那个我发现可以使用函数的内容缓存参数,更接近函数式编程;就是我们想方法让x,y,z传递给第二个按钮的回调函数里面,就可以不使用全局变量了。那么怎么做呢?聪明的小伙伴可以想想,在不使用全局变量的情况下怎么把x,y,z传递给按钮2的回调事件呢? 好吧直接上代码:

Function.prototype.setCallback = function(thisObj,...arg) {
    this.cache = this.bind(thisObj,arg);
}
Function.prototype.getCallback = function(...arg) {
    if(this.cache){
        return this.cache(arg);
    }
    return this(arg);
}

let btn1 = document.querySelector('#btn1');
let btn2 = document.querySelector('#btn2');
function btn2Event(x,y,z,objthis,e) {
    console.log(x,y,z,objthis,e);
}
btn1.addEventListener('click',function(e){
    let x = 1;
    let y = 2;
    let z = 3;
    btn2Event.setCallback(null,x,y,z)
});
btn2.addEventListener('click',function(e){
    //使用参数缓存
    btn2Event.getCallback(this,e);
    //不使用参数缓存
    btn2Event(1,2,3,this,e)
})

这样在btn2Event回调函数里面可以拿到所用的参数了,并且可以给任何函数设置缓存参数,如果不使用缓存,就直接使用原函数调用

知识点:

在javascript中函数也是对象,所有我们可以给函数定义属性,细心的朋友可以打应btn2Event.cache这个,就是缓存的函数。

同时在js中的bind方法当执行一次时,返回的函数会把之前的参数缓存起来,后面添加的参数依次添加到参数后面,bind执行一次后的函数的this是无法再次执行bind改变函数里面的this指向的。

对于cache的封装还可以使用Symbol进行封装,这样外面就无法拉取这个属性

const cache = Symbol();
Function.prototype.setCallback = function(thisObj,...arg) {
    this[cache] = this.bind(thisObj,arg);
}
Function.prototype.getCallback = function name(...arg) {
    if(this[cache]){
        return this[cache](arg);
    }
    return this(arg);
}

点赞~~~~