惰性载入函数
如果if语句没必要每次都执行,代码可以更快运行。解决办法就是惰性载入函数
1.在函数被调用时再处理函数
创建一个变量,if中的每个分支都会为变量赋值,有效覆盖了原有的函数,最后一步就是调用新赋的函数。
2.在声明函数时就指定适当的函数。1.返回一个函数,2.匿名自执行。
函数绑定
使用bind进行绑定。bind()中使用了apply改变了fn的上下文环境。arguments是内部匿名函数的,而非bind的。所以可以拿到对应的event参数。
unction bind(obj,context){
return function(){
obj.apply(context, arguments)
}
}
函数柯里化
柯里化是指这样一个函数(假设叫做createCurry),他接收函数A作为参数,运行后能够返回一个新的函数。并且这个新的函数能够处理函数A的剩余参数。
** 通用的封装**
var currying = function(fn) {
// args 获取第一个方法内的全部参数
var args = Array.prototype.slice.call(arguments, 1)
return function() {
// 将后面方法里的全部参数和args进行合并
var newArgs = args.concat(Array.prototype.slice.call(arguments))
// 把合并后的参数通过apply作为fn的参数并执行
return fn.apply(null, newArgs)
}
}
bind
function bind(fn,content){
var args=Array.prototype.slice.call(arguments,2);
return function(){
fn.apply(content,args.concat(Array.prototype.slice.call(arguments)));
}}
// 支持多参数传递
function progressCurrying(fn, args) {
var _this = this
var len = fn.length;
var args = args || [];
return function() {
var _args = Array.prototype.slice.call(arguments);
Array.prototype.push.apply(args, _args);
// 如果参数个数小于最初的fn.length,则递归调用,继续收集参数
if (_args.length < len) {
return progressCurrying.call(_this, fn, _args);
}
// 参数收集完毕,则执行fn
return fn.apply(this, _args);
}
}
防篡改对象
不可扩展对象
不可扩展(不可添加、可以删除、可以修改、可以查)
【增、删、改、查】 --> 【删、改、查】
Object.preventExtension(obj) 禁止扩展
Object.isExtensible(obj) 判断是否可以扩展
密封的对象
(不可添加、不可删除、可以修改、可以查)密封对象不可扩展,不可删除
【增、删、改、查】 – Object.seal() --> 【改、查】
Object.seal() 密封对象
Object.isSealed 对象是否密封
冻结的对象
(不可添加、不可删除、不可修改、可以查)
【增、删、改、查】 – Object.freeze() --> 【查】
Object.freeze()
Object.isFrozen()
函数防抖
防抖和节流是针对响应跟不上触发频率这类问题的两种解决方案。 在给DOM绑定事件时,有些事件我们是无法控制触发频率的。 如鼠标移动事件onmousemove, 滚动滚动条事件onscroll,窗口大小改变事件onresize,瞬间的操作都会导致这些事件会被高频触发。 如果事件的回调函数较为复杂,就会导致响应跟不上触发,出现页面卡顿,假死现象。
定义:多次触发事件后,事件处理函数只执行一次,并且是在触发操作结束时执行。
原理:对处理函数进行延时操作,若设定的延时到来之前,再次触发事件,则清除上一次的延时操作定时器,重新定时。
let timer;
window.onscroll = function () {
if(timer){
clearTimeout(timer)
}
timer = setTimeout(function () {
//滚动条位置
let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
console.log('滚动条位置:' + scrollTop);
timer = undefined;
},200)
}
不适用:
当我们做图片懒加载(lazyload)时,需要通过滚动位置,实时显示图片时,如果使用防抖函数,懒加载(lazyload)函数将会不断被延时,只有停下来的时候才会被执行,对于这种需要实时触发事件的情况,就显得不是很友好了。
var timer = false;
document.getElementById("debounce").onscroll = function(){
clearTimeout(timer); // 清除未执行的代码,重置回初始化状态
timer = setTimeout(function(){
console.log("函数防抖");
}, 300);
};
函数节流
定义:触发函数事件后,短时间间隔内无法连续调用,只有上一次函数执行后,过了规定的时间间隔,才能进行下一次的函数调用。原理:对处理函数进行延时操作,若设定的延时到来之前,再次触发事件,则清除上一次的延时操作定时器,重新定时。
var canRun = true;
document.getElementById("throttle").onscroll = function(){
if(!canRun){ // 判断是否已空闲,如果在执行中,则直接return
return;
}
canRun = false;
setTimeout(function(){
console.log("函数节流");
canRun = true;
}, 300);
};
图中每一个断点都代码触发了一次函数,但是触发函数时只在奇数时执行,偶数时不执行,断点间的时间间隔为50ms。
函数节流
let startTime = Date.now(); //开始时间
let time = 500; //间隔时间
let timer;
window.onscroll = function throttle(){
let currentTime = Date.now();
if(currentTime - startTime >= time){
let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
console.log('滚动条位置:' + scrollTop);
startTime = currentTime;
}else{
clearTimeout(timer);
timer = setTimeout(function () {
throttle()
}, 50);
}
}