摘要:闭包带来的问题内存占用由于闭包使用其它函数内的变量,所以垃圾回收机制不会对闭包相关的函数进行回收,占用内存空间。
什么是闭包?
“在函数内使用其它函数内的变量,是为闭包”
【例1】 function a() { let num = 100; return function b() { console.log(num) } } var c = a() c() // 100
在例 1 中,a 为外层函数,a中返回了一个内部函数 b , 函数 b 中使用了 a 中的 num 变量。此时,函数 b 就形成了一个闭包。
闭包的用处是什么?在JavaScript中,作用域链使得子作用域能够读取到父作用域的变量【见例2】,而反过来,父作用域无法直接获取子作用域的变量【见例3】。
【例2】 let num = 100 function a() { console.log(num) } a() // 100 【例3】 function a() { let num = 100 } console.log(num) // error: not defined
当我们想在父作用域使用子作用域的值时该怎么办呢?
答:那就在函数内部再定一个函数,将其作为返回值即可【例4】。
【例4】 function a() { let num = 100 return function b() { return num } } var x = a() console.log(x()) // 100
例 4 中,函数 b 作为函数 a 的内部函数,可以访问 a 中的变量 num,于是我们将函数 b 作为返回值,我们通过操作 b 来访问 a 的变量。
上述利用闭包的特性来实现外部对内部的访问,便是闭包最基本的应用。
闭包的应用场景一般来说,我们只想让外界使用我们暴露出去的方法,而方法涉及到的变量计算想要封装在函数内部,以避免被有意/无意地修改变量值,此时,便可利用闭包来进行变量封装以控制权限【例5】。
【例5】 // 判断输入的变量是否是第一次输入 function isFirstVisit() { let _list = [] return function (id) { if (_list.indexOf(id) >= 0) { console.log("Exist!") } else { _list.push(id) console.log("Added~") } } } let firstVisit = isFirstVisit() firstVisit(5) // Added~ firstVisit(5) // Exist! firstVisit(10) // Added~
将 isFirstVisit 的返回值赋给 firstVisit ,然后通过使用 firstVisit 进行判断,因为暴露给外界使用的是 firstVisit 函数,所以只能使用该函数定义的方法,而无法对 _list 进行任何修改,保证了数据的私密性。
函数柯里化就是把一个函数接收多个参数进行处理,转变为接收单一参数,然后返回一个新函数接收下一个参数【见例6】。
【例6】 // 普通函数 function sum(x, y) { return x + y } // 函数柯里化 function curryingSum(x) { return function(y) { return x + y } }
这里函数柯里化后的内部函数所使用的 x,就是其父作用域的变量,此时的内部函数就是一个闭包。
函数柯里化应用之 参数复用
【例7】 function check(reg, txt) { return reg.test(txt) } // 检验是否含有数字 check(/d+/g, "test") // false check(/d+/g, "abc") // false check(/d+/g, "2dd") // true // 柯里化后 function curryingCheck(reg) { return function(txt) { return reg.test(txt) } } let hasNumber = curryingCheck(/d+/g) hasNumber("test") // false hasNumber("abc") // false hasNumber("2dd") // true
通过上例可以看到,直接使用check函数,第一个参数“正则判断语句”在每次使用时都需要输入,既不美观也不方便。对其进行函数柯里化后,只需输入一次正则判断语句,便可对判断函数进行复用。
闭包带来的问题由于闭包使用其它函数内的变量,所以垃圾回收机制不会对闭包相关的函数进行回收,占用内存空间。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/104309.html
摘要:所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。所以本文中将以维基百科中的定义为准即在计算机科学中,闭包,又称词法闭包或函数闭包,是引用了自由变量的函数。 闭包(closure)是JavaScript中一个神秘的概念,许多人都对它难以理解,我也一直处于似懂非懂的状态,前几天深入了解了一下执行环境以及作用域链,可戳查看详情,而闭包与作用域及作用域链的关系密不可分,所...
摘要:执行环境变量对象活动对象作用域链执行环境,为简单起见,有时也称为环境是中最为重要的一个概念。作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问。闭包垃圾回收机制先介绍下垃圾回收机制。 执行环境、变量对象 / 活动对象、作用域链 执行环境(executioncontext,为简单起见,有时也称为环境)是JavaScript中最为重要的一个概念。执行环境定义了变量或函数有...
摘要:使用单引号双引号和三引号或来表示字符串。不可变的集合函数会以字典类型返回当前位置的全部全局变量。用于将进制整数转换成进制,以字符串形式表示。返回字符串中最大的字母,或数组中的最大值。的作用就是减少了单行函数的定义。 问题答案由本人整理 1.基础语法是否熟悉?介绍一下 Python和其他语言最大的区别就是使用行和缩进,而不是大括号({})或者分号(;)来控制类、函数或者逻辑判断。Pyt...
阅读 612·2021-11-22 15:32
阅读 2710·2021-11-19 09:40
阅读 2275·2021-11-17 09:33
阅读 1250·2021-11-15 11:36
阅读 1848·2021-10-11 10:59
阅读 1465·2019-08-29 16:41
阅读 1737·2019-08-29 13:45
阅读 2132·2019-08-26 13:36