闭包:简单来说就是函数内返回函数
效果:可以让变量使用保存在内存中不被释放,再者就是可以引用内部变量
function person(){
var name = 'bob';
function getName(){
return name;
}
return getName;
}
console.log(person()()); //输出bob;
//这就是一个闭包,创建私有变量的一个好方法;但是,通过它看不出闭包的特性,我们用下面的案例来看
//
var addN=null;
function addSelf(){
var n = 0;
addN = function(){
n++;
}
function retN(){
return n;
}
return retN();
}
console.log(addSelf()()); //0
addN();
console.log(addSelf()()); //1
//变量n一直放在内存中,即使addSelf函数调用完成也没有被释放,第二次执行又在自身基础上自加。
- 我们简单来说一下他的内部原理:
我们在执行addSelf函数的时候,函数内部抛给了我们他的内部函数retN;现在的指针就指向了retN函数而不是addSelf本身,相对于retN而言,n是一个外部变量,retN就对变量n形成了引用(你可以说是构成依赖),因为addN需要他,n就不会释放,当第一次调用时,retN返回变量n,然后执行了addN函数,内部私有变量n自加了,对于retN来说,addN改变了他的外部变量,所以再次调用时返回的是1而不是0;
闭包在开发过程中单独使用的情况很少,但他是JS封装的基础(包括模块封装和面向对象等),后面我们会用到。
防抖,主要涉及滚动、mouseover等操作,在规定时间内只能执行一次
function debounce(fn,time){
let timeout = null;
return function(){
let _this = this;
let _args = arguments;
if(timeout!==null){
clearTimeout(timeout);
}
timeout = setTimeout(function(){
fn.apply(_this,_args)
},time);
}
}
let utils = {}
utils.prototype.debounce = debounce // 挂载到原型链,哪里需要哪里用
节流,节流用处比较大[重点],涉及秒杀等高频操作需要用到
function throttle(func, time) {
let timeout = null;
return function(){
let _this = this;
let _args = arguments
if(!timeout){
timeout = setTimeout(function(){
timeout = null;
func.apply(_this,_args)
},time)
}
}
}
防抖和节流的主要区别在于防抖是规定时间内执行一次,如果规定时间内再次触发,重置时间。节流是规定时间内只执行一次函数,不重置时间。