继承和闭包

时间:2022-06-23
本文章向大家介绍继承和闭包,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

继承和闭包

继承

概述:

父类拥有属性及相关方法,通过继承、子类也可以拥有(私有的不能获取)

  • 你爸爸拥有1000万 你就可以继承你爸爸的1000万

  • 你爸爸秃头,可能你不会秃头

继承的实现方式

es6的extends关键词来实现继承(class)

class Person{
constructor(){

}
}
class Son extends Person{
constructor(){
super() //指向父类的构造函数 如果要使用this关键词
}
}

原型继承(将对应的需要继承的对象加在原型上 )


function Person(){
   this.name = "哈哈"
}
function Son(){
   this.age = 18
}
//原型继承 将对应的继承的对象 赋值给对应的原型
Son.prototype = new Person()

通过this指向来继承


function Person(){
   this.name = "哈哈"
}
function Son(){
  //this指向Son的实例对象
  Person.call(this) //将Person的this指向改为对的son的实例对象
}

组合继承


function Person(){
   this.name = "哈哈"
}
function Son(){
  //this指向Son的实例对象
  Person.call(this) //将Person的this指向改为对的son的实例对象
}
//原型继承 将对应的继承的对象 赋值给对应的原型
Son.prototype = new Person()

闭包

函数的执行过程


function fn(){
   var message = 'hello'
   var number = 0
   number++
console.log(message)
   console.log(number)
}
fn() //执行完 以后message会被回收 number值为1
fn() //执行完 以后message会被回收 number值为1
1.预编译
  • 先开辟一个内存空间装函数对象

  • 在对应的内存空间上再开辟一个空间 代码块空间(来装代码)

2.执行
  • 找到函数的对象空间 在这个对象空间上开辟一个执行空间

  • 再将对应的代码块空间合并到执行空间里面去 进行代码的执行

  • 执行完毕 执行空间销毁 对应的代码块空间也会被销毁

  • 对应的代码块里面的内容就会垃圾回收机制回收

对应的流程走完了以后那么我们在对应的函数代码块里面声明的变量就会全部回收。也就是第一次执行函数里面的变量和第二次执行函数里面的变量不是一个。如果我想要对应的变量不回收(这个时候俩个变量就是是同一个)?

解决办法:再开一个空间 将数据存入 这个空间跟执行空间没有关系。


function fn(){
retrun {
name:'jack'
}
}
//执行函数fn 接收他的返回值 执行完函数对应的执行空间就销毁了
var obj=fn()
console.log(obj)

那么就知道想让对应的函数内容的内容不回收 我们需要返回一个对象 将数据存入这个对象就不会被回收。

那么我们知道对应的函数也是一个对象 所以也可以返回一个函数 那么这个东西叫做闭包。

闭包的概念:

1.在函数内部返回函数

2.内部函数要存储对应外部函数内的引用

3.那么这个数据就不会被回收 (持久化)

优点

1.持久化 可以作为缓存

2.不会造成数据的全局污染 (外部的内容不会直接访问函数的变量)

缺点

1.因为不会被回收 那么内存空间会一直占用

2.会一直保持引用

示例

function sum(){
let number = 10
return function(){
number++
console.log(number)
}
}
var fn = sum() //返回的是一个函数
fn() //11
fn() //12

闭包的应用

防抖 (提交表单)

概念:在一定时间间隔内,执行一个内容的时候 只执行最后一次

举例

电梯间隔二十秒关门关上、a进来的时候 等上二十秒 在这个二十秒没等完 b来关门操作被终止了 b进来了又开始20s关门操作 20s还没到c过来了,b的关门操作又被终止了,c进来 执行c的关门操作 (关门操作只执行一次 执行最后一次)


function antiShake(fn,time){
var timer = null
return function(){
clearTimeout(timer) //清除上一次
timer = setTimeout(()=>{ //这个一次操作
//操作
//console.log('关门')
           fn()
},time)
}
}
节流(事件处理)

概述:在规定的时间内执行一次 执行第一次(总共会执行多次)

示例

有个出租车 亮红灯就是有客 亮绿灯就是没客 他首先第一次没客 a上来了 这个时候对应的灯应该是红灯 当a执行完后 切换完绿灯

b继续上来 灯再变成红灯 b执行完后 灯变为绿灯 c上来 灯再次变成红灯 灯c执行完变成绿灯


function throttle(fn,time){
var timer = null //阀门
return function(){
//先判断节流阀 是否开启 如果开启直接出去
if(timer) return;
//如果节流阀为null 操作
timer = setTimeout(()=>{
//console.log('帅哥!!去哪')
           fn()
//执行完毕 将节流阀设置为null
timer = null
},time)
}
}
节流和防抖区别

节流 只会在规定时间内执行一次 (执行第一次) (总共会执行多次)

防抖 在一定间隔内只会执行一次 (执行最后一次)(总的只会执行一次)

函数柯里化(颗粒化)

概述: 将多个参数的方法 拆分为多个一个参数的方法

简单的函数柯里化

普通求和函数


//普通的函数
function sum(a,b){
return a+b
}
var number = sum(10,20)
console.log(number)

函数柯里化


//函数柯里化 做拆分 将多个参数方法 拆分为多个一个参数的方法
//简单函数柯里化
function fn(a){
   return function(b){
       return a+b
  }
}
// 调用
console.log(fn(10)(20));
高阶函数柯里化

function currying(fn){
   let arg = Array.prototype.slice.call(arguments,1)//做切割
   //统计参数 每次取一个
   return function(){
       //将原本有的参数和我这个参数做拼接 [1,2,3]
       var newArgs = arg.concat(Array.prototype.slice.call(arguments))
       //参数个数没到返回的是一个函数
       if(newArgs.length<fn.length){//传入的参数 不等于对应的函数里面需要参数 这个时候返回一个对应的函数
           return currying.call(this,fn,...newArgs) //这个地方this指向会变 因为这个里面会无限返回函数
      }else{
           //参数个数到了返回对应的结果
           return fn.apply(this,newArgs)
      }
  }
}
var fn2 = currying(sum1)
console.log(fn2(1)(2,3));
console.log(fn2()()(1)(2)()(3));
console.log(fn2()()(1)()(2)()(3));
console.log(fn2()()()()()()()()()(1,2,3));

原文地址:https://www.cnblogs.com/itxun/p/16406423.html