代码开发的格式 - 注意冲突和依赖
开发项目的时候有很多种写法,像模块化开发,命名空间,闭包…,闭包其实就是一种写法
闭包:它是JavaScript独有的一种函数结构(一种函数的嵌套用法)
闭包的形成与变量的作用域以及变量的生存周期密切相关,变量的作用域,就是指变量的有效范围。生存周期对于全局变量是永久的,除非我们主动销毁这个全局变量。而对于在函数内用 var 关键字声明的局部变量来说,当退出函数时,这些局部变量即失去了它们的价值,它们都会随着函数调用的结束而被销毁:
讲一下作用域链:
当声明一个函数时,局部作用域一级一级向上包起来,就是作用域链。
函数的内部有个[[scope]]的内部属性,它在函数创建的时候会有全局对象;函数执行的时候会有活动对象;为什么函数里的对象函数外获取不到呢?是因为函数在执行完,活动对象自行销毁
形成闭包的三个条件
- 函数嵌套
- 内层函数使用了外层函数的变量或参数
- 内层函数被返回到外部 在外部调用 ( 将内层函数作为返回值 )
闭包的作用
- 隔离作用域 避免作用域污染
- 保护具有共享意义的变量 为变量提供相关的操作接口
闭包的缺点
- 占用内层空间 大量使用闭包会造成 栈溢出
- 使用过于复杂
如何销毁闭包?
将闭包函数赋值为null 可以销毁闭包
实例:
function fn() {
var num = 100;
function fn2() {
// 由于内层函数使用外层函数的变量
// 并且内层函数被返回到外部
// 导致局部变量引用未释放 (局部变量没有销毁)
// 一直存在在内层中
num += 50;
console.log(num);
}
return fn2;
}
var fn2 = fn();
fn2();//打印结果150
fn2();//打印结果200
注意:自执行函数不是闭包,但是自执行函数可以达到闭包的效果,同时它也可以写成闭包
闭包函数的应用:
什么是高频事件?
高频事件 指的是 触发频率高的事件
例如oninput,onkeypress,onscroll,resize等事件触发频率非常高
高频事件性能优化-函数节流
核心思想:在连续触发的事件中,一定的时间内只执行一次我们的函数。
需要两个时间
第一个时间:上次的执行时间 ;
第二个时间:间隔时间
当前时间-上次执行时间 >= 2000ms
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#box {
width: 300px;
height: 300px;
background-color: red;
}
</style>
</head>
<body>
<div id="box"></div>
<script>
window.onload=function(){
function fn(callback,wait){
let prev=0;// prev 用于记录上次执行的时间
return function(){
let args=arguments;//参数
let now=Date.now();//获得当前时间
if(now-prev>=wait){
callback.apply(this,args);//修改this指向,传入形参
prev=now;// 将当前的时间记录为上一次的执行时间
}
}
}
let box=document.getElementById('box');
box.addEventListener('mousemove',fn(function(ev){
console.log('执行了 move');
console.log(ev);
},2000));
}
</script>
</body>
</html>
高频事件性能优化-函数防抖
比如说大家非常熟悉的搜索引擎的联想查询功能。它是在用户进行键入的同时进行的数据请求。
但是键盘事件触发的频率是按照字母来计算的,不是按照汉字或者单词,如果是每键入一个字母都触发一次数据请求,就非常的低效。在这种情况下,我们就有必要降低这种操作的频率,保证一定时间内,核心代码只执行一次。这样在核心代码块比较沉重的时候,就会大大提升我们的性能了。
核心思路:是指触发时间后再n秒内只能执行一次,如果再n秒内又触发了该事件,则重新计算时间
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="text" id="search">
<script>
window.onload=function(){
//防抖
function fn(callback,wait){
let timer=null; // 记录计时器的id
return function(){
let args=arguments;
if(timer) clearTimeout(timer);
timer=setTimeout(function(){
callback.apply(this,args);
}.bind(this),wait);
}
}
let search=document.getElementById('search');
search.addEventListener('input',fn(function(){
let script=document.createElement('script');
script.src="https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web&sugsid=32095,1422,31326,21125,31069,31253,32045,30823,26350&wd="+this.value+"&req=2&csor=3&pwd=12&cb=callBack&_=1592456567512";
document.body.appendChild(script);
document.body.removeChild(script);
},2000));
}
function callBack(data){
console.log(data);
}
</script>
</body>
</html>