给搜索框添加一个属性,实现这个表单输入的时候,不会弹出记录框! -启用自动完成功能的表单(其中一个输入字段禁用了自动完成)
这边会使用到节流和去抖的知识:有兴趣的可以看这一篇文章
链接: link.
闭包
01:函数调用 => 产生一个新的执行环境
02:变量对象 => 用来存储代码执行之中的数据(就是变量对象)
注意点;window对象是一个持续存在的对象,负责存储全局环境下得所有变量和对象!
03:活动对象 => 变量对象只在函数活动期间存在
注意点:函数执行完毕后,这个被销毁的变量就是活动对象!
function funA() {
a = 100;
}
funA();
//在函数funA调用的时候,会创建一个执行环境,来存储函数funA执行时候创建的数据(比如这个a = 100),因此函数A也是有着自己的变量对象!
//但是这个变量对象在编译的时候存在,也就是说,在funA调用后,会创建一个变量对象a=100,当函数执行完毕的时候,就销毁了这个变量!
注意点:这个销毁的变量就是活动对象!
变量的概念
在函数内部返回一个匿名函数,在这个匿名函数之中引用这个变量。
- 在闭包的情况下会产生一个特殊的变量(自由变量);
- 全局变量 : 生命周期(永久) 可访问性( 在任意地方都可以被访问 )
- 局部变量 : 生命周期 (函数执行结束立即删除) 可访问性 (仅在函数内部可以被访问)
- 自由变量 : 生命周期 (永久) 可访问性 (仅在函数内部访问);
自由变量
- 作用:
- 01:在任意时间内被调用,不会被销毁!
- 02:保证数据的隐私性 => 只有你的函数可以使用;
var a = 100;
function funA() {
a = 100;
return function () {
//这个变量a在内部被使用到,也就是说,变量a不会被销毁!
console.log(a);
}
}
funA()
//在函数内部返回一个匿名函数,在匿名函数内部引用这个变量a,匿名这个变量为自由变量!
// 一个需求 :
// 1. 这是一个考试系统;
// 2. 会把所有的数据发送给前端包括答案;
// 3. 考试结束实时给予评分。(前端完成);
// - 你答案放在哪里 ?
// 需求难点 :
// 1. 请求一次返回所有数据 : 1. 答案 2. 试题;
// 2. 答案这个东西考虑到我们需要在后面使用 , 我们是不是应该把这样的数据放在全局中那 ?
// 1 需要持久的保存数据;
// 2 这个数据只有在我们的程序之中可以访问;
// 伪代码 :
function load(){
// 请求之中会获取到试题和答案;
return $.ajax( {} )
}
load().then( function( data ){
// 答案
var ans = data.ans;
// 试题;
var que = data.que;
renderQue( que );
return function(){
// 使用 ans;
console.log(ans);
}
})
闭包的作用1:
需求:点击ul中的li,输出对应的索引号
//需求:使用闭包的方式,来点击当前的小li获取到当前的小li的索引号
var lis = document.querySelectorAll("li");
for (var i = 0; i < lis.length; i++) {
//利用闭包的方式,把当前的i当做参数传递到立即执行函数内部,才出发当前的点击事件,打印对应的索引号!
(function (num) {
lis[i].onclick = function () {
console.log(num);
}
})(i)
}
闭包的作用2:封装函数
- 1:节流函数的封装
//需求:利用闭包的方式,封装一个用于节流和防抖的函数
//throttle --- 节流 antiShake ---防抖
//节流的封装
// 参数1:回调函数(里面书写的是消耗性能方面的函数) 参数2:延迟时间 参数3:改变this的指向!
function throttle(callback, delay, context) {
var flag = true;
delay = delay || 100;
return function () { //产生闭包
if (flag) {
flag = false;
setTimeout(function () {
context ? callback.call(context) : callback();
flag = true;
}, 200)
}
}
}
// document.onscroll = throttle(function () {
// console.log("消耗性能的函数");
// }, 200)
- 2:封装一个去抖的函数
//去抖的封装
//参数1:回调函数 参数2:延迟时间 参数3:改变this的指向
function antiShake(callback, delay, context) {
var timer = "";
var delay = delay || 100;
return function () { //产生闭包
clearInterval(timer)
timer = setTimeout(function () {
context ? callback.call(context) : callback();
}, 200)
}
}
// document.onscroll = antiShake(function () {
// console.log("消耗性能的2");
// }, 200)
- 3:把节流和去抖封装为一个函数
// 封装一个节流和去抖的函数
//参数1:节流还是去抖的方式(th-节流,ant-去抖) 参数2:回调函数(事件处理函数)
//参数3:延迟时间 参数4:改变this的指向
function funPerformance(type, callback, delay, context) {
delay = delay || 100;
flag = true;
timer = "";
return function () {
switch (type) {
//节流
case "th":
if (flag) {
flag = false;
setTimeout(function () {
context ? callback.call(context) : callback();
flag = true;
}, 200)
}
break;
//去抖
case "ant":
clearInterval(timer)
timer = setTimeout(function () {
context ? callback.call(context) : callback();
}, 200)
break;
}
}
}
//调用的时候:
document.onscroll = funPerformance("ant", function () {
console.log("消耗性能的2");
console.log(this); //这边的rhis指向的window ,所以要是使用到this的时候,我们可以在后面修改为前面的调用者
}, 200, document)