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>