闭包

js 从两道面试题加深理解闭包与箭头函数中的this

£可爱£侵袭症+ 提交于 2019-12-06 10:58:17
壹 ❀ 引 在本文之前我已经花了两个篇幅专门介绍了JavaScript中的闭包与this,正好今早地铁上看到了两道面试题,试着做了下发现挺有意思,所以想单独写一篇文章来记录解析过程。若你对于闭包与this有所了解,不妨先看自己的理解是否正确,若你对于这部分知识欠缺,还是建议先阅读我前面的两篇文章,链接在下: 一篇文章看懂JS闭包,都要2020年了,你怎么能还不懂闭包? js 五种绑定彻底弄懂this,默认绑定、隐式绑定、显式绑定、new绑定、箭头函数绑定详解 那么本文开始。 贰 ❀ 题一 /*非严格模式*/ var name = 'window' var obj1 = { name: '听风是风', fn1: function () { console.log(this.name) }, fn2: () => console.log(this.name), fn3: function () { return function () { console.log(this.name) } }, fn4: function () { return () => console.log(this.name) } } var obj2 = { name: '行星飞行' }; obj1.fn1();//? obj1.fn1.call(obj2);//? obj1.fn2();//? obj1

什么是闭包,闭包造成的内存泄露如何解决

限于喜欢 提交于 2019-12-06 08:43:30
什么是闭包? 能够访问其他函数内部变量的函数 闭包解决了什么问题 由于变量的作用域的原因-----(函数内部能读取全局变量,函数外部无法读取函数内部的变量【局部变量】),为了在函数外部读取局部变量,所以就有了闭包。 闭包的作用 1.访问其他函数内部变量 2.保护变量不被内存回收机制回收 3.避免全局变量被污染 方便调用上下文的局部变量 加强封装性 闭包的缺点 闭包长期占用内存,内存消耗很大,可能导致内存泄露 闭包示例代码 function outer(){ var m = 2; function inner(){ console.log(m) } return inner; } let func = outer(); func() //打印2 注意事项,如若操作不当,可能会导致内存泄漏。 什么是内存泄漏 首先,需要了解浏览器自身的内存回收机制。 每个浏览器会有自己的一套回收机制,当分配出去的内存不使用的时候便会回收;内存泄露的根本原因就是你的代码中分配了一些‘顽固的’内存,浏览器无法进行回收,如果这些’顽固的’内存还在一直不停地分配就会导致后面所用内存不足,造成泄露。 闭包造成内存泄漏 因为闭包就是能够访问外部函数变量的一个函数,而函数是必须保存在内存中的对象,所以位于函数执行上下文中的所有变量也需要保存在内存中,这样就不会被回收,如果一旦循环引用或创建闭包,就会占据大量内存

Scala学习笔记-3-函数

ぃ、小莉子 提交于 2019-12-06 08:39:22
package day04 import java.io.{File, PrintWriter} class Demo(desc: String) { override def toString: String = desc } object Demo { def main(args: Array[String]): Unit = { val d = new Demo("Scala 函数") println(d) test_1() test_2() test_3() test_4() test_5() // test_6() test_7() test_8() test_9() } // 类成员函数,和 Java 的成员方法一致,略 /** * 局部函数:在函数内部定义函数 * 在局部函数中可以访问外部定义的变量 * */ def test_1(): Unit = { val v_1 = "hello " def innerFun(): Unit = { println(v_1 + "inner function") } innerFun() } /** * 函数字面量(就是匿名函数) * 函数是 Scala 中的“头等公民”(W3C中这句话不知道什么意思。。。) * 匿名函数看起来不能指定返回值类型(语句最后一行执行的结果就是返回值) */ def test_2(): Unit

Python 之路Day13

元气小坏坏 提交于 2019-12-06 08:39:22
匿名函数 一行函数 lambda == def -- 关键字 lambda x:x x 是普通函数的形参(位置,关键字……)可以不接收参数,可以不写 :x 是普通函数的函数值(只能返回 一个 数据类型),必须写 匿名函数的名字叫做lambda lst=[lambda :i for i in range(5)]print(lst[0]())#结果:4 函数体中存放的是代码,生成器体中存放的也是代码 yield导致函数和生成器的执行结果不统一 内置函数二 重点讲解 : enumerate() open() range() len() str() list() tuple() dict() set() print() sum() abs() dir() zip() format() reversed() filter() map() sorted() max() min() reduce() 普通 str() list() tuple() dict() set() print() sum() abs() dir() zip() format() reversed() 分讲: print() -- abs() -- 取绝对值 dir() -- 查看当前对象所有方法 zip() -- 拉链 format() -- 格式、转换 reversed() -- 反转 高阶 filter() map(

闭包函数

ぐ巨炮叔叔 提交于 2019-12-06 08:38:27
# 闭包函数:定义在函数内部的函数,该函数的函数体代码包含对外部作用域(而不是全局作用域)名字的引用# def outer():# x=1# def inner():# print(x)# return inner## f=outer()# print(f) # <function outer.<locals>.inner at 0x000001F6C8F74C18># print(f.__closure__) # __closure__ 闭合 (<cell at 0x000001605D38A078: int object at 0x00007FFD2F717110>,)# print(f.__closure__[0]) # <cell at 0x0000021A6471A078: int object at 0x00007FFD2F717110># print(f.__closure__[0].cell_contents) # 1# def outer():# x=1# y=2# def inner():# print(x,y)# return inner## f=outer()# print(f.__closure__[0].cell_contents) # 1# print(f.__closure__[1].cell_contents) # 2# z=3# def

JS高阶---闭包(循环遍历+监听)

半城伤御伤魂 提交于 2019-12-06 08:22:26
大纲: 主体: (1)场景1:点击按钮显示点击的第几个 注意:伪数组每次循环时都会重新计算一次长度,所以最好提出去或者直接加到for循环内部 结果: 分析:   1、i为全局变量      解决方案:   1、下标法        2、闭包法          变量分类与读取:      【闭包理解】 (1)首先做下断点测试 (2)自定义验证:   (3)闭包条件验证: (4)验证方式 通过Chrome调试工具的debug调试工具进行断点测试,进行查看 (5)闭包产生条件 最后必须调用执行函数定义,注意 不一定要调用内部函数才会产生闭包 ,上面断点测试即可看出。验证如下 修改: 【常见的闭包】 (1)将函数作为另外一个函数的返回值       将fn2函数作为fn1函数的返回值 (2) . 来源: https://www.cnblogs.com/jianxian/p/11971649.html

听说你还不理解JavaScript闭包

会有一股神秘感。 提交于 2019-12-06 07:39:10
闭包(Closure) 闭包是一个函数和词法环境的组合,函数声明在这个词法环境中 词法作用域 看下面一个例子 function init() { var name = 'Mozilla'; // name是局部变量 function displayName() { // displayName()是内部函数,一个闭包 alert(name); // 使用外部函数声明的变量 } displayName(); } init();    init() 创建了一个局部变量 name 和一个函数 displayName() 。函数displayName()是一个已经定义在init()内部的函数,并且只能在函数init()里面才能访问得到。函数displayName()没有自己的局部变量,但由于内部函数可以访问外部函数变量,displayName()可以访问到声明在外部函数init()的变量name,如果局部变量还存在的话,displayName()也可以访问他们。 闭包 看下面一个例子 function makeFunc() { var name = 'Mozilla'; function displayName() { alert(name); } return displayName; } var myFunc = makeFunc(); myFunc();  

js学习:函数

拈花ヽ惹草 提交于 2019-12-06 07:21:38
概述 函数的声明 JavaScript 有三种声明函数的方法 function 命令 function命令声明的代码区块,就是一个函数。function命令后面是函数名,函数名后面是一对圆括号,里面是传入函数的参数。函数体放在大括号里面。 这叫做函数的声明(Function Declaration)。 function print(s) { console.log(s); } 函数表达式 除了用function命令声明函数,还可以采用变量赋值的写法。 var print = function(s) { console.log(s); }; 这种写法将一个匿名函数赋值给变量。这时,这个匿名函数又称函数表达式(Function Expression),因为赋值语句的等号右侧只能放表达式。 采用函数表达式声明函数时,function命令后面不带有函数名。如果加上函数名,该函数名只在函数体内部有效,在函数体外部无效。 var print = function x(){ console.log(typeof x); }; x // ReferenceError: x is not defined print() // function 上面代码在函数表达式中,加入了函数名x。这个x只在函数体内部可用,指代函数表达式本身,其他地方都不可用。这种写法的用处有两个,一是可以在函数体内部调用自身

闭包(python)

人盡茶涼 提交于 2019-12-06 07:11:10
1.闭包的理解 我们可以将闭包理解为一种特殊的函数,这种函数由两个函数的嵌套组成,且称之为外函数和内函数,外函数返回值是内函数的引用,此时就构成了闭包。 2. 闭包的格式 下面用伪代码进行闭包格式的描述 def 外层函数(参数): def 内层函数(): print("内层函数执行", 参数) return 内层函数 内层函数的引用 = 外层函数("传入参数") 内层函数的引用() 外层函数中的参数,不一定要有,据情况而定,但是一般情况下都会有并在内函数中使用到 案例 def func(a, b): def line(x): return a * x - b return line line = func(2, 3) print(line(5)) 结果得到 7 在这个案例中,外函数func有接收参数 a=2,b=3,内函数line接收参数x=5,在内函数体中计算了a*x-b 即 2×5-3的值作为返回值,外函数返回内函数的引用,这里的引用指的是内函数line在内存中的起始地址,最终调用内函数line()得到返回值7 3.内函数中修改外函数的值 一般在函数结束时,会释放临时变量,但在闭包中,由于外函数的临时变量在内函数中用到,此时外函数会把临时变量与内函数绑定到一起,这样虽然外函数结束了,但调用内函数时依旧能够使用临时变量,即闭包外层的参数可以在内存中进行保留

python的闭包

人走茶凉 提交于 2019-12-06 06:53:11
一、思考一个问题 我们要给定一个x,要求一条直线上x对应的y的值。公式是y = kx+b。 我们需要用k,b来确定这条直线,则我们实现的函数应该有3个参数: def line(k, b, x): print(k * x + b) line(1, 3, 4) line(1, 3, 5) line(1, 3, 6) 可以看到,我们每次修改x都要重新传入k和b。 我们也可以用全局变量来实现: k = 1 b = 3 def line(x): print(k * x + b) line(4) line(5) line(6) k和b为全局变量,但如果我们想要另外一条不同的直线时,则还需要重新定义k和b的值,同样不合理。而且全局变量会暴露给其他不相关的函数,容易造成冲突,或代码混乱。 用面向对象来实现: class Line(object): def __init__(self, k, b): self.k = k self.b = b def create_y(self, x): print(self.k * x + self.b) l1 = Line(1, 3) l1.create_y(4) l1.create_y(5) l1.create_y(6) 用类和对象来实现肯定是可以的,但是这么一个简单的功能使用面向对象比较浪费资源。 二、使用闭包 def line(k, b): def