js闭包的理解

你如何理解 JavaScript 中的闭包?

闭包是定义在一个函数内部的函数

闭包的实现是借用作用域和作用域链

作用域是指存储、访问变量的规则。
作用域按书写方式,分为全局作用域、函数作用域和块级作用域,函数作用域和块级作用域又统称为局部作用域。
作用域按划分作用域的时机,分为词法作用域和动态作用域。

词法作用域:在代码书写的时候完成划分,作用域链沿着他定义的位置往外延伸(平时我们写代码的方式,都是词法作用域)
动态作用域:在代码运行时完成划分,作用域链沿着他的调用栈往外延伸

如何改变词法作用域?
使用eval或者with,
eval改变作用域的方式是,eval函数在运行时,改变了作用域的内容
with改变作用域的方式是,with会创建作用域,在运行时,还是会根据词法作用域的方式向外查找,如果没找到,最后创建一个全局变量

js是一边编译一边执行的,

编译阶段的时候,当我们声明一个变量的时候,编译器会遍历当前作用域,看该变量是不是已经被声明过,如果有,就忽略该声明,如果没有,
就在当前作用域里新增该变量

执行阶段的时候,js引擎执行代码时,会遍历当前作用域,如果能找到该变量,就进行赋值操作,如果找不到,会变量当前作用域的外层
作用域,如果还没找到,就会继续再往外一层,直到找到为止,如果最终都没找到,引擎就会抛出异常

引擎的这种查找过程,就是作用域套作用域的作用域链

对闭包重新理解,不是函数参数,又不属于当前作用域的变量,相对于当前作用域来说,叫自由变量,引用了自由变量的函数就称作闭包。

LHS,是变量出现在操作的左侧,意味着变量赋值或写入内存,强调的是一个写入的动作,比如: var name = 1;
RHS,是变量没出现在操作的左侧,意味着变量查找或从内存中读取,强调的是读的动作,比如:var myname = name; 和cosnole.log(name)

闭包的应用:
1、模拟私有变量的实现
2、偏函数与柯里化
柯里化是把接受 n 个参数的 1 个函数改造为只接受 1 个参数的 n 个互相嵌套的函数的过程。也就是 fn (a, b, c)fn(a,b,c) 会变成 fn (a)(b)(c)fn(a)(b)(c)。
强调的是“单参数”的概念
偏函数是固定函数的某一个或几个参数,然后返回一个新的函数(这个函数用于接收剩下的参数,它的目标仅仅是把函数的入参拆解为两部分。

 

posted @ 2020-04-08 16:16  小小泡zdy  阅读(485)  评论(0编辑  收藏  举报