首先奉上JS设计模式学习链接:https://www.cnblogs.com/imwtr/p/9451129.html#o1
下面代码内容主要是:
通过手机防抖这一功能的实现来解释js的代理模式
// 函数防抖,频繁操作中不处理,直到操作完成之后(再过 delay 的时间)才一次性处理
function debounce(fn, delay) {
delay = delay || 200;
var timer = null;
return function() {
var arg = arguments;
// 每次操作时,清除上次的定时器
clearTimeout(timer);
timer = null;
// 定义新的定时器,一段时间后进行操作
timer = setTimeout(function() {
fn.apply(this, arg);
}, delay);
}
};
var count = 0;
// 主体
function scrollHandle(e) {
console.log(e.type, ++count); // scroll
}
// 代理
var proxyScrollHandle = (function() {
return debounce(scrollHandle, 500);
})();
window.onscroll = proxyScrollHandle;
简单理解思路:函数防抖,频繁操作中不处理,直到操作完成之后(再过 delay 的时间)才一次性处理
但是我这里要讲的是
fn.apply(this, arg);
这段代码,我要分享的也是这个:一个是argument这个属性 另一个就是apply的应用
当我看到
fn.apply(this, arg);
这句我当时就疑惑了,fn(arg)不行吗 试了一下,不行!为什么是fn.apply(this, arg);?
首先理解一下 argument
argument属性的内容是 它会把传给当前函数的参数使用一个类似于数组的形式保存起来
argument = {"0": param1, "1": param2, ... }
在函数里面argument在特定情况下可以被当作数组处理,也就有了配合apply的用法
因为apply的通常是apply(obj,[param1, param2]),而本身argument就是一个类数组的东西,如果直接fn(argument),那么在fn的方法里面的argument(argument2)就变成了 argument2 = {'0':argument} 而不是argument2 = {"0": param1, "1": param2, ... }
所以这里传参数要用 fn.apply(this, arg);才能使fn实际上是得到的fn(param1, param2)这样的参数