摘要:由于闭包函数是由调用的,所以一般它的指向。因为闭包记住了它定义时候的作用域呀,这个时候的是块级的,能够好好地保存起来被闭包函数使用。
定义
当函数可以记住并访问它定义时候的作用域,就产生了闭包。也就是说,一个函数在另外一个函数里面定义,但是它执行的时候,可能是在其他的作用域,但是它还是能够凭着出生时的回忆,找到定义时的作用域,去访问里面的变量。
function foo() { var a = 2; function bar() { console.log(a) } return bar; } var bar = foo(); bar();//记住了定义时的作用域,所以还是可以访问到a,这里会输出2
为什么能够访问到定义时候的作用域呢?答案只有一个,定义闭包的函数是个重情义的家伙,考虑到那个宝宝可能随时要用到它里面的变量,都不肯被回收。没错,这样会导致foo的作用域一直没有被回收,有一点浪费内存空间。
关于this对象一般函数的this指向的是调用它的对象。由于闭包函数是由window调用的,所以一般它的this指向window。如果你需要让它指向某个对象,可以用call或者把外部的this保存起来,在里面直接使用。
var name = "window"; var object = { name: "My Object", //var that = this; getNameFunc: function() { return function() { console.log(this.name); //console.log(that.name); } } } object.getNameFunc()();//输出"window" object.getNameFunc().call(object);//输出"My Object"循环和闭包
很常见的一段代码,运行结果就是输出5个5。因为这里的i没有块级作用域,也就是说闭包里面的函数访问到外部的变量i只有一个,加上setTimeout是异步的,执行到里面的回调的时候,外面的这个i的值就是循环结束后的值5。
for(var i = 0; i < 5; i++) { setTimeout(function() { console.log(i); }, 1000) }
在没有let的时候,我们都是通过模仿块级作用域来解决。这个时候,闭包函数定义的作用域变成了(function(){}),然后在这个作用域里面把i的值赋值给j,每个闭包函数访问到的j就是它定义时候作用域已经保存好了的,自然就能够正确的输出。
for(var i = 0; i < 5; i++) { (function() { var j = i; setTimeout(function() {//闭包 console.log(j); }, 1000) })() }
当然,我们一般都舍不得再用一个j来保存,直接用传参数的形式,让块级作用域可以访问到i的值。
for(var i = 0; i < 5; i++) { (function(j) { setTimeout(function() {//闭包 console.log(j); }, 1000) })(i) }
简单改一下,每次用个块级作用域的let来保存一下是不是就可以了啊
for(var i = 0; i < 5; i++) { let j = i; setTimeout(function() { console.log(j); }, 1000) }
哈哈哈,真的就输出0 1 2 3 4 5了。因为闭包记住了它定义时候的作用域呀,这个时候的j是块级的,能够好好地保存起来被闭包函数使用。
其实就是相当于每次循环都会去声明一个j,然后这个j的作用域就属于这次循环,所以可以直接把j的赋值写在for循环里。
for(let j = 0; i < 5; i++) { setTimeout(function() { console.log(j); }, 1000) }模块化
可以使用闭包来实现模块化的。
var module = (function(window) { function test1() { } functon test2() { } return { test1: test1, test2: test2 } })(window)
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/95393.html
摘要:闭包可以用来在一个函数与一组私有变量之间创建关联关系。夹带私货外部变量返回的是函数,带私货的函数支持将函数当成对象使用的编程语言,一般都支持闭包。所以说当你的装饰器需要自定义参数时,一般都会形成闭包。 Python中的闭包不是一个一说就能明白的概念,但是随着你往学习的深入,无论如何你都需要去了解这么一个东西。 闭包的概念 我们尝试从概念上去理解一下闭包。 在一些语言中,在函数中可以(嵌...
摘要:完美的闭包,对,闭包就这么简单。这仅仅是闭包的一部分,闭包利用函数作用域达到了访问外层变量的目的。此时一个完整的闭包实现了,的垃圾回收机制由于闭包的存在无法销毁变量。 1.闭包是指有权访问另一个函数作用域中的变量的函数。 上面这段话来自 javascript 高级程序设计 第三版 P178 。作者说闭包是一个函数,它有访问另一个函数作用域中的变量的能力。 2.函数访问它被创建时所处的...
摘要:在计算机科学中,闭包又称词法闭包或函数闭包,是引用了自由变量的函数。闭包被广泛应用于函数式语言中。运用闭包可以避免对全局变量的使用。将栈顶的元素取出,创建元组,并将该元组进栈。 在计算机科学中,闭包 又称 词法闭包 或 函数闭包,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。闭包被广泛应用于函数式语言中。 从上面这段话中可以看出闭...
摘要:朋友,这就是闭包的效果。那么函数就是一个闭包,它可以在作用域外被访问。封闭函数必须返回至少一个内部函数,这样内部函数才能在私有作用域中形成闭包,并且可以访问或者修改私有的状态。的模块机制中为模块增加了一级语法支持。 闭包 闭包是什么? 当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行,简单上讲,就是在一个函数中内部的函数。 function fo...
摘要:注理论上讲闭包和匿名函数是不同的概念,不过将其视作相同的概念。匿名函数可以从父作用域继承变量,而这个父作用域是定义该闭包的函数不一定是调用它的函数。 匿名函数 匿名函数,也叫闭包函数,说白了就是没有名字的函数,和一般函数结构一样,只是少了函数名以及最后需要加上分号;。 注:理论上讲闭包和匿名函数是不同的概念,不过PHP将其视作相同的概念。 $func = function() { ...
摘要:译者按在上一篇博客,我们通过实现一个计数器,了解了如何使用闭包,这篇博客将提供一些代码示例,帮助大家理解闭包。然而,如果通过代码示例去理解闭包,则简单很多。不过,将闭包简单地看做局部变量,理解起来会更加简单。 - 译者按: 在上一篇博客,我们通过实现一个计数器,了解了如何使用闭包(Closure),这篇博客将提供一些代码示例,帮助大家理解闭包。 原文: JavaScript Clos...
阅读 1601·2021-09-02 15:41
阅读 1003·2021-09-02 15:11
阅读 1287·2021-07-28 00:15
阅读 2313·2019-08-30 15:55
阅读 1149·2019-08-30 15:54
阅读 1698·2019-08-30 15:54
阅读 2981·2019-08-30 14:02
阅读 2530·2019-08-29 16:57