ES6的继承、闭包、节流、防抖
闭包:
<script>
/*
小目标
让外部作用域让函数里面的变量
解决方案:
在外部函数fn函数里面再套一个函数,形成了一个函数的嵌套关系
在内部函数当中,直接访问这个变量
在外部函数当中返回内部函数
像这种外部函数里面套一个函数,形成了函数的嵌套关系 => 我们叫做闭包
闭包形成的条件
内部函数引用了外部的变量的局部变量
闭包在哪里?
如图
闭包的作用:
1.闭包当中的变量会一直存在于内存当中,可以一直给我们来进行使用
(访问函数内部变量、保持函数在环境中一直存在,不会被垃圾回收机制处理)
2.外部作用域可以访问函数内部的变量
闭包的缺点:
因为局部变量会一直存在于内存当中,所以会一直占用这内存空间,对于IE低版本的浏览器来说,容易造成内存泄露,消耗内存
闭包的应用场景
为什么要使用闭包?
对于普通函数来讲,函数执行完毕之后,会释放掉其内存空间
闭包,不会主动的释放内存空间
使用闭包完毕之后:
手动的来释放空间
f = null;
*/
function fn(){
var a = 10;//这个变量会一直存在于内存中,一直提供给我们来进行使用
/* 在函数里面再套一个函数,形成一个函数的嵌套关系 */
/* 这个内部函数要被调用 */
function inner(){
//在内部函数当中,直接访问这个变量
return a;
// console.log(a);
}
//在外部函数当中直接返回内部函数
return inner;
}
var f = fn();//得到这个f=>整个内部函数
// console.log(f);//输出了这个内部函数
//用完之后,记得手动方式
f = null;
// console.log(f());//获取到了外部函数里面的这个变量
</script>
节流:
<script>
/* 在处理某一些业务的时候,短时间触发大量的事件,对浏览器造成的很大的压力,导致浏览器的性能变差 */
/* 使用节流来提高效率 */
//开始时间
let firstTime = 0;
document.onmousemove = function(e){
/* 获取当中时间的事件戳 */
let nowTime = +new Date();
if(nowTime - firstTime < 1000){
//不要让代码往后面走,就是不要触发事件
return;
}
//下一个时间段,又是从头开始
firstTime = nowTime;
//执行业务代码
console.log("=============");
console.log(e);
console.log("=============");
}
</script>
封装节流:
<script>
/* 将业务代码与节流代码剥离出来 */
//业务代码
function fn(e){
console.log("=============");
console.log(e);
console.log("=============");
}
document.onmousemove = throttle(fn,1000);
//节流函数
function throttle(fn,time){
//开始时间
let firstTime = 0;
return function(){
//获取当中的时间戳
let nowTime = +new Date();
/* 使用节流触发时间的频率 */
if(nowTime - firstTime < time){
/* 在触发时间频率之内,代码不要往后面走 */
return;
}
//当进入在一个时间频率,firstTime = nowTime
firstTime = nowTime
// console.log(arguments[0]);
//触发业务代码
fn.call(this,arguments[0]);
}
}
/* 只触发一次 */
// document.onmousemove = fn();
</script>f
防抖:
<!--
我们估摸着用户一般2000触发打完账号
节流:
短时间当中触发大量事件=>短时间当中触发少次事件
防抖:
短时间连续触发事件=>短时间触发一次事件
-->
账号: <input type="text" placeholder="请输入账号" id="inp">
<script>
//业务代码
function fn(e){
console.log("=============");
console.log(e);
console.log("=============");
}
//键盘起来事件
inp.onkeyup = debounce(fn,2000)
function debounce(fn,time){
let timer = null;
return function(){
clearTimeout(timer)
timer = setTimeout(() => {
fn.call(this,arguments[0]);
}, time);
}
}
</script>
ES6和ES6的继承:
<script>
/*
面向对象三大特征:
封装继承多态
在ES6类当中,继承的关键字是extends
*/
class Animal{
/* 属性 */
constructor(name,age){
this.name = name;
this.age = age;
}
//方法
eat(){
console.log("动物吃");
}
}
/* 创建一个狗类 */
class Dog extends Animal{
}
//创建一个狗
let d = new Dog("阿黄",18);
d.eat();
console.log(d);
/* 创建一个猫类 */
class Cat extends Animal{
}
let c = new Cat("喵喵",2);
c.eat();
console.log(c);
</script>
ES6的super:
<script>
/* 创建动物类 */
class Animal{
//构造器
constructor(name,age){
console.log("这个是父类的构造方法");
this.name = name;
this.age = age;
}
eat(){
console.log("动物吃");
}
}
//创建一个狗类 static 关键字 super关键字
class Dog extends Animal{
constructor(name,age){
// /* 调用父类的构造器 */
super(name,age);
}
}
let d = new Dog("张三",12);
console.log(d);
</script>
ES6继承DS5:
<script>
/* 使用ES5创建一个动物类 */
function Animal(name,age){
this.name = name;
this.age = age;
}
//在原型身上添加一个吃的方法
Animal.prototype.eat = function(){
console.log("动物吃");
}
class Dog extends Animal{
// constructor(name){
// super(name,19)
// }
}
let d = new Dog("张三",18);
console.log(d);
d.eat();
</script>
拓展ES6的继承:
<script>
class Ainmal{
constructor(name,age){
this.name = name
this.age = age
}
eat(){
console.log("父级");
}
}
class Dog extends Ainmal{
eat(){
console.log("子级");
}
}
let d = new Dog("小明",10)
console.log(d); //输出的时小明和10
d.eat() //自身有的话就不会调用父级的
</script>
ES5的原型继承:
/*
所有的函数自娘胎里面出来就是一个属性 prototype
所有的对象自娘胎里面出来就一个对象 __proto__
*/
/* 创建一个动物的构造函数 */
function Animal(name,age){
this.name = name;
this.age = age;
}
/* 在动物的构造函数当中添加一个吃的方法 */
Animal.prototype.eat = function(){
console.log("动物吃");
}
//创建一个动物实例对象
let a = new Animal("动物",12);
// console.log(a);
//创建一个狗的构造函数
function Dog(){
}
//让狗的构造函数的原型继承动物的那个对象 原型继承
Dog.prototype = a;
// Dog.prototype = new Animal("动物",12);
//创建一个狗
let d = new Dog();
// console.log(d);
d.name = "阿黄"
d.age = 2;
console.log(d.name);
console.log(d.age);
d.eat();
</script>
</body>
构造继承:
<script>
/* 创建一个动物的构造函数 */
function Animal(name,age){
this.name = name;
this.age = age;
}
/* 在动物的构造函数当中添加一个吃的方法 */
Animal.prototype.eat = function(){
console.log("动物吃");
}
//创建一个狗类
function Dog(name,age){
// console.log(Animal);//构造继承,或者是call继承,不能继承方法
Animal.call(this,name,age)
}
let d = new Dog("阿黄",3);
console.log(d);
// d.eat();//构造继承不能继承方法
</script>
组合继承:
<script>
/* 创建一个动物的构造函数 */
function Animal(name,age){
this.name = name;
this.age = age;
}
/* 在动物的构造函数当中添加一个吃的方法 */
Animal.prototype.eat = function(){
console.log("动物吃");
}
/* 组合继承=原型继承+构造继承 */
function Dog(name,age){
/* 构造继承 */
Animal.call(this,name,age);
}
//原型继承
Dog.prototype = new Animal();
let d = new Dog("阿黄",3)
console.log(d);
d.eat();
</script>
浙公网安备 33010602011771号