闭包
-
闭包的优点
可以让外部函数访问内部函数的变量
延长局部变量的生命周期 -
闭包的缺点
闭包会一直占内存空间,容易导致低版本IE浏览器内存泄漏。需要手动释放内存空间。 -
闭包的条件
1. 需要一个不销毁的函数
2. 需要一个嵌套函数
3. 内部函数访问外部函数里面的变量
/* 不销毁的函数 */
function fn() {
//这个变量会一直存在内存地址中
var a = 10;
/* 函数嵌套 */
function f1(){
/* 函数内部要访问外部函数变量 */
console.log(a);
}
return f1;
}
let f = fn();
f();
节流
一段时间内大量触发事件,会对浏览器的性能造成很大的压力,
一段时间当中执行一次。
let firsttime = 0
document.onmousemove = function(e){
let nowtime = +new Date()
if(nowtime - firsttime < 500){
return
}
firsttime = nowtime
console.log(e)
}
- 节流封装
//业务代码
function fn(e){
console.group()
console.log(e)
console.groupEnd()
}
//节流代码
function throttle(fn,time){
let firsttime = 0
return function(e){
let nowtime = +new Date()
if(nowtime - firsttime < time) return
firsttime = nowtime
fn(e)
}
}
//触发事件
document.onmousemove = throttle(fn,1000)
防抖
一段时间当中执行最后一次
封装防抖代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="text">
</body>
</html>
let inp = document.querySelector('input')
//业务代码
function fn(e){
console.group()
console.log(e);
console.groupEnd()
}
//触发防抖
inp.oninput = debounce(fn,1000)
//防抖代码
function debounce(fn,time){
let timer = null
return function(e){
if(timer){
clearTimeout(timer)
}
timer = setTimeout(function(){
fn.call(this,arguments[0])
},time)
}
}
继承(extends)
继承父类中的属性和方法
- ES6的继承
constructor => 给属性赋值
class Animal{
//ES6的属性写在constructor中
constructor(name,age,gender){
this.name = name
this.age = age
this.gender = gender
}
eat(){
console.log(this.name + '吃');
}
}
class dog extends Animal{}
let d = new dog("小黑",10,"公")
d.eat()
console.log(d);
- ES6的继承之重写
class Animal{
/* constructor => 给属性赋值的 */
constructor(name,age,gender){
this.name = name;
this.age = age;
this.gender = gender;
}
// 方法
eat(){
console.log(this.name + "吃!");
}
}
class dog extends Animal{
//重写 => 将继承下来的父类里面的内容给重新写一遍
eat(){
console.log(this.name + "玩");
}
}
let d = new dog("小黑",8,"公")
d.eat()
console.log(d);
- ES6继承super
super调用父类里面的构造器
class Animal {
/* constructor => 给属性赋值的 */
constructor(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
eat() {
console.log(this.name + "吃!");
}
}
class dog extends Animal{
// super调用父类里面的构造器
constructor(name,age,gender){
super('小白',5,'母')
}
}
let d = new dog('小黑',4,'公')
console.log(d);
- ES6继承ES5
function Animal(name,age,gender){
this.name = name;
this.age = age;
this.gender = gender;
}
Animal.prototype.eat = function(){
console.log('吃');
}
class dog extends Animal{}
let d = new dog('小黑',9,'雄')
d.eat()
console.log(d);
- ES5的原型继承
Dog.prototype = new Animal()
继承方法好用,但是属性不好用
function Animal(name,age,gender){
this.name = name;
this.age = age;
this.gender = gender;
}
Animal.prototype.eat = function(){
console.log("吃");
}
function Dog(){}
//原型继承
Dog.prototype = new Animal()
let d = new Dog()
d.name = '小黑'
d.age = '8'
d.gender = '公'
d.eat()
console.log(d);
构造继承(call继承)
只能继承属性
function Animal(name,age,gender){
this.name = name;
this.age = age;
this.gender = gender;
console.log(this);
}
Animal.prototype.eat = function(){
console.log("吃");
}
function Dog(name,age,gender){
Animal.call(this,name,age,gender);
}
//创建一对象
let d = new Dog("小黑",8,"公")
console.log(d);
组合继承
组合继承 = 构造继承+原型继承
function Animal(name,age,gender){
this.name = name;
this.age = age;
this.gender = gender;
}
Animal.prototype.eat = function(){
console.log("吃");
}
function Dog(name,age,gender){
//构造继承
Animal.call(this,name,age,gender)
}
/* 构造继承 */
Son.prototype = new Animal();
let s = new Dog("小黑",8,"公")
s.eat();
console.log(s);