一.闭包的概念

闭包是这样的一种机制:函数嵌套函数,内部函数可以引用外部函数的参数和变量。参数和变量不会被垃圾回收机制收回。

1.函数嵌套函数

function fn(a){return function(){//访问道这个aconsole.log(a);}}console.log(fn('hello'));//调用外部的函数fn('hello')()//调用内部函数

2.作用域

function fn1(){let i = 0  //i不会被垃圾回收机制回收return function(){i++return i}}console.log(fn1()()); //1console.log(fn1()()); //1let a = fn1()console.log(a());//1console.log(a());//2console.log(a());//3

3.垃圾回收机制有两种:1.标记清除, 2.引用计数

1.标记清除:js会对变量做一个标记yes or no的标签以供js引擎来处理,当变量在某个环境下被使用则标记为yes,当超出改环境(可以理解为超出作用域)则标记为no,然后对有no的标签进行释放。

2.引用计数:对于js中引用类型的变量, 采用引用计数的内存回收机制,当一个引用类型的变量赋值给另一个变量时, 引用计数会+1, 而当其中有一个变量不再等于值时,引用计数会-1, 如果引用计数为0, 则js引擎会将其释放掉。

二.闭包的作用

相比全局变量和局部变量,闭包有两大特点:

1.闭包拥有全局变量的不被释放的特点

2.闭包拥有局部变量的无法被外部访问的特点

闭包的好处:

1.可以让一个变量长期在内存中不被释放

2.避免全局变量的污染,和全局变量不同,闭包中的变量无法被外部使用

3.私有成员的存在,无法被外部调用,只能直接内部调用

闭包可以完成的功能:1.防抖、2.节流、3.函数柯里化

1.防抖

//防抖 避免函数的重复调用 只会调用一次function Antishake(fn,wait){ //第一个参数是函数 第二个参数是毫秒值let timer = null //声明一个变量来接收延时器 初始值为nullreturn function(){clearTimeout(timer)timer = setTimeout(() => {fn() //调用这函数}, wait);}}let an = Antishake(function(){ //用一个变量接收console.log('555');},2000)document.querySelector('div').onmouseenter = ()=>{an() //调用一次}

2.节流

function throttle(fn,wait){let timer = null //节点闸return function(){if(timer) return //null false 不是null结果减少true 如果上传没有我就直接跳过 没有人我就上去timer = setTimeout(() => { //上车了fn()timer = null //做完之后重新关闭节点闸}, wait);}}let throttle1 = throttle(()=>{console.log('我上车了');},2000)document.querySelector('div').onclick = ()=>{throttle1()}

节流和防抖的区别

防抖避免重复执行 只执行一次

节流 减少执行次数 执行多次

3.函数柯里化

函数柯里化 其实就是函数颗粒化 将一个函数变成一个个颗粒可以组装,就是这个里面的多个参数 将他变成一个个的函数来传递这个参数。

简单柯里化函数:

 function fnSum(a,b,c){//求和函数return a+b+c}//简单柯里化 他就是使用了一个函数来改造原本的函数function curry(fn){return function(a){return function(b){return function(c){return fn(a,b,c)}}}}//调用 避免了多余的无用参数传递let fnCurry = curry(fnSum) //函数console.log(fnCurry(1)(2)(3));//6

改进的柯里化函数:

function fnSum(a,b,c){//求和函数return a+b+c}
function curry1(fn){//接收一个后面的参数 除了fn的参数let args = Array.prototype.slice.call(arguments,1)//从下标1开始全部剪切  把Array里面的slice方法加给外部函数的argumentsreturn function(){let newArg = args.concat(Array.from(arguments)) //将内部函数的参数和外部的参数合并return fn.apply(this,newArg) //将内部函数自动指向 传入所有的参数}}let fn2 = curry1(fnSum,1,2) //函数console.log(fn2(3)); //6

最终改进的柯里化函数:可以任意组合传参 如果不满足就返回偏函数 如果满足就返回结果

function fnSum(a,b,c){//求和函数return a+b+c}
function curry2(fn){//接收一个后面的参数 除了fn的参数let args = Array.prototype.slice.call(arguments,1)return function(){let newArg = args.concat(Array.from(arguments)) //将内部函数的参数和外部的参数合并if(newArg.length < fn.length){ //参数没有到三个 fn.length获取传递的函数的参数个数return curry2.call(this,fn,...newArg) //又套了一个function  这个this指向这个function 如果没有到达会一直套这个方法}else{return fn.apply(this,newArg) //将内部函数自动指向 传入所有的参数 } }}let fn3 = curry2(fnSum) //函数console.log(fn3(1)()(2)()(3)); //6console.log(fn3()(1)()(2)()()); //偏函数  function

三.this指向以及this的绑定

1.this指向问题

在构造函数里面this指向对象

function Box(name) { this.name = name;this.show = function(){ console.log(this.name);}
}
var box = new Box('zhangsan');

在普通函数里面谁调用就指向谁

function func() {    console.log(this);
}
func();  //window对象

在定时器里面this指向window

setInterval(function(){console.log(this); //window对象}, 2000);    

在事件函数中this指向触发这个事件的标签

box.onclick = function() {console.log(this);//this指向box
}     

2.this绑定的方法

bind() 里面传递的是对应指向的对象

call() 里面传递的是指向的对象和参数(会自动调用)

apply() 里面传递时指向的对象及参数数组(会自动调用)

function fn(name){ //函数this.name = nameconsole.log(this);}fn('李四') //this指向windowfunction Student(){this.name = 'hello'this.age = 18}let student = new Student()//bind 里面传递的是对应指向的对象fn.bind(student)('李四')//call 里面传递的是指向的对象和参数fn.call(student,'王五') //name参数王五 自动调用方法//apply 里面传递时指向的对象及参数数组fn.apply(student,['赵六']) //传递一个参数数组 自动调用方法

相同点:call、apply和bind都是JS函数的公有的内部方法,他们都是重置函数的this,改变函数的执行环节。

不同点:bind是创建一个新的函数,而call和aplay是用来调用函数;call和apply作用一样,只不过call为函数提供的参数是一个个的,而apply为函数提供的参数是一个数组。

什么是闭包?以及闭包的作用相关推荐

  1. 什么是闭包,闭包的作用与好处是什么,何时使用闭包,对闭包的改进

    闭包:外部函数定义的内部函数就是闭包.闭包的作用及好处:闭包给访问外部函数定义的内部变量创造了条件.也将关于函数的一切封闭到了函数内部,减少了全局变量,这也是闭包的真实含义.与普通函数的区别:1,普通 ...

  2. 什么是闭包?闭包有啥作用?闭包的应用有啥?内存优化?

    什么是闭包?闭包的应用有哪些? 是不是很多人一开始所了解的闭包是一个函数套着另一个函数,然后其他的函数可以引用里面的函数的变量(很久之前俺就是这么理解的)?看完这篇文章后,球球泥们不要再这么回答了好嘛 ...

  3. 闭包的两大作用:保存/保护

    闭包的概念 函数执行时形成的私有上下文EC(FN),正常情况下,代码执行完会出栈后释放;但是特殊情况下,如果当前私有上下文中的某个东西被上下文以外的事物占用了,则上下文不会出栈释  放, 从而形成不销 ...

  4. python闭包到底有什么作用

    本文转载于https://blog.csdn.net/qq_27825451/article/details/79964128,并对代码格式做了修正. 1.global关键字的作用 如果在函数中需要修 ...

  5. 什么是闭包?闭包有什么作用?

    概念: 闭包是变量作用域的特殊情况,以下情况会产生闭包 函数作为参数被传递 函数作为返回值被传递 闭包的作用: 被闭包引用的变量,不会被销毁 闭包可以实现局部变量,避免全局变量污染 闭包执行过程: 闭 ...

  6. 闭包、闭包作用及缺点

    闭包:是指有权访问另一个函数作用域中的变量的函数.创建闭包的常见形式:就是在一个函数内部创建另一个函数. 词法作用域 function outer(){var localVal = 30;functi ...

  7. js闭包的理解和作用

    一.为什么引入闭包 JS为每个变量对象定了作用域,在ES5 中只有全局作用域和函数作用域,没有块级作用域,由内向外形成作用域链,函数外部不能访问函数内部作用域的局部变量.在实际开发中会带来很多不便. ...

  8. 什么是闭包以及闭包有什么作用

    <script>//什么是闭包:就是函数作用域 --closure//全局:global/*--函数出生时会自动保存所在的词法作用域,词法作用域意思就是所在的作用域们--词法作用域会被保存 ...

  9. 了解js基础知识中的作用域和闭包以及闭包的一些应用场景,浅析函数柯里化

    js基础知识中的作用域和闭包 一.作用域 1.作用域.自由变量简介 (1)作用域定义 (2)作用域实例演示 (3)自由变量定义 (4)自由变量实例演示 2.作用域链简介 (1)作用域链定义 (2)作用 ...

  10. PHP性状闭包,PHP 闭包及Closure类

    原标题:PHP 闭包及Closure类 匿名函数 实现一个简单的匿名函数: $func = function { echo "this is a funcn"; }; 上面就是一个 ...

最新文章

  1. idea插件手动安装
  2. python最基本的规则是什么_Python基础介绍(一)
  3. Python 过滤字母和数字
  4. Boost:双图bimap与range范围的测试程序
  5. Web网页布局的主要方式 1
  6. 学术诚信的重要性_申论作文开头之诚信
  7. 设计一个笔记本电脑类,属性随意,并且进行属性私有化,对外提供公开的set和get方法。 设计一个可插拔的接口:InsertDrawable,该接口有什么方法自行定义。
  8. Python学习指南高清PDF版,速存!24小时后删除
  9. linux每日命令(1):which
  10. Docker在centos下安装以及常见错误解决
  11. 推荐系统实践(四)----基于标签的推荐算法
  12. Eoapi — 一个可拓展的开源 API 工具
  13. 快播宣称将转型关闭QVOD服务器
  14. TweenMax逐帧动画
  15. HTML——表格、表格嵌套、表格布局
  16. js jq 按钮开始/停止转换
  17. 金融行业网络架构与技术探讨
  18. ERR_ABORTED 404
  19. 区块链项目 - 2 工作量证明
  20. c语言---图形打印

热门文章

  1. Vue3管理后台项目使用高德地图选点
  2. MAC本地服务器搭建
  3. 化工厂人员精确定位系统监测预警
  4. 机器学习-隐私保护总览
  5. ARM嵌入式编译器-volatile关键字对编译器优化的影响
  6. CVPR 2023上46篇AIGC论文和代码
  7. 【MAPBOX基础功能】15、mapbox地图事件:点击、移入、移出、解绑
  8. PathPlanning常用路径规划算法实现与动画
  9. MySQL 设计数据表时,时间类型 datetime、bigint、timestamp MySQL日期函数
  10. Vue组件的八个钩子函数