资讯专栏INFORMATION COLUMN

JavaScript闭包(closure)的学习

tianren124 / 1460人阅读

摘要:下面让我们来看一个例子上面就是一个最简单的闭包。闭包的作用接下来来谈谈闭包的作用,初学者刚接触时肯定是一脸懵逼,闭包的用处究竟是什么,下面就来谈一谈。同时也得感谢参考文章闭包的应用让你分分钟理解闭包闭包,懂不懂由你,反正我是懂了

昨天在看思否时,发现了一篇文章是关于JavaScript如何实现重载的,由于以前也和学长讨论过JavaScript是否能够重载,就点进去看了看,发现里面的两个方法的其中一个需要用闭包实现,就看了几篇博客学习了一下,顺便写篇博客加深一下印象。
(JavaScript重载的文章在这:https://segmentfault.com/a/11...)

什么是闭包

闭包的本质是一个函数

闭包可以访问函数内部变量

闭包的存在会使内部变量保留在内存中

这个可以说是闭包比较容易让人理解又比较全面的解释了,更通俗一些:当function里嵌套function时,内部的function可以访问外部function里的变量。

下面让我们来看一个例子:

function A(){
    function B(){
       console.log("Hello Closure!");
    }
    return B;
}
var C = A();
C();// Hello Closure!

上面就是一个最简单的闭包。

就下来让我们来看一下下面这个函数,他是不是一个闭包呢?

 function foo(x) {
  var tmp = 3;
  function bar(y) {
    alert(x + y + (++tmp));
  }
  bar(10);
}
foo(2);

答案是:并不是,重新看一下闭包的定义,就明白了:

它能吗?明显不能,当你return的是内部function时,就是一个闭包。

function foo(x) {
  var tmp = 3;
  return function (y) {
    alert(x + y + (++tmp));
  }
}
var bar = foo(2); // bar 现在是一个闭包
bar(10);

至于能保存的原因,看了看网友的解释:

由于内部函数嵌套在foo中,导致内部函数的作用域链上添加了foo的作用域;而当内部函数被返回后,也要保证其作用域链有效,因此,函数foo的作用域不得不被保留在内存中以供内部函数访问。
闭包的作用

接下来来谈谈闭包的作用,初学者刚接触时肯定是一脸懵逼,闭包的用处究竟是什么,下面就来谈一谈。

一.模仿块级区域

首先简单举个例子来,解释一下什么是块级作用域:

function A(num) {
    for (var i = 0; i < num; i++) {
      num++;
    }
    console.log(i)
  }

在这个简单的函数中,变量i是在for循环中定义的,如果是在C++或者Java中,这样定义的变量,一旦循环结束,变量也就随之销毁,i的作用范围只在循环这个小块,就称为块级作用域。在javascript中,没有这样的块级作用域,前面一篇文章已经提到,变量是定义在函数的活动对象中的,因此,从定义i开始,在函数内部可以随时访问它。
这样的坏处显而易见:由于javascript不会告诉你变量是否已经被声明,容易造成命名冲突,如果是在全局环境定义的变量,就会污染全局环境,因此可以利用闭包特性来模拟块级作用域

明白了块级作用域,接下来看看js怎么实现的吧:

function A(num) {
    //下面是一个匿名立即执行函数
    //核心代码
   (funnction(){
    for(var i = 0; i

使用这个就可以有效的避免全局污染,也许有人会对匿名立即执行函数为什么是一个闭包感到困惑,如果有这个问题可以点击这里查看

二.存储变量

闭包的另一个作用是可以保存外部函数的变量

function StorageVariable(){
    var x = 100;
    return {
        function(){
            return x
        }
    }
}

var test = StorageVariable();//运行StorageVariable函数,生成活动变量 x被test引用

这种写法可能会用在把一些不经常变动,但是计算比较复杂的值保存起来,就可以节省每次访问的时间.

三.封装私有变量

javascript中没有私有成员的概念,我们可以把函数当做一个范围,函数内的变量就是私有变量:

function Person(){
    var name = "default";
    this.getName = function(){
        return name;
    }
    this.setName = function(value){
        name = value;
    }
}
var person = new Person()
console.log(person.getName())//default
console.log(person.setName("mike"))
console.log(person.getName())//mike

这样就可以像私有变量一样访问和改变person的name了。

总结

不得不说写博客总结对学习这种比较难的东西真的很有用,明明我昨天感觉自己已经大概弄明白了,但在写着写着的时候又陷入了困惑,虽然写完这个不敢说已经完全弄懂了,但至少比昨天强了,但要完全掌握还任重而道远,还得靠多使用。同时也得感谢

参考文章
js闭包的应用
让你分分钟理解 JavaScript 闭包
闭包,懂不懂由你,反正我是懂了

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/98204.html

相关文章

  • 通过示例学习JavaScript闭包

    摘要:译者按在上一篇博客,我们通过实现一个计数器,了解了如何使用闭包,这篇博客将提供一些代码示例,帮助大家理解闭包。然而,如果通过代码示例去理解闭包,则简单很多。不过,将闭包简单地看做局部变量,理解起来会更加简单。 - 译者按: 在上一篇博客,我们通过实现一个计数器,了解了如何使用闭包(Closure),这篇博客将提供一些代码示例,帮助大家理解闭包。 原文: JavaScript Clos...

    xingpingz 评论0 收藏0
  • 学习Javascript闭包Closure

    摘要:另一方面,函数外部无法直接读取函数内的局部变量。这说明,函数中的局部变量一直保存在内存中,并没有在调用后被自动清除。首先函数没有使用关键字来声明,因此是一个全局变量,而不是局部变量。解决方法是,在退出函数之前,将不使用的局部变量全部删除。 原文链接 - http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures...

    LeoHsiun 评论0 收藏0
  • The Little JavaScript Closures

    摘要:写在前面本文尝试模仿的风格,介绍的闭包。本文同时也是我学习闭包的一次总结。注根据这篇文章,事实上所有函数在创建的时候都会形成闭包。但这种闭包并没什么趣味,也没什么特别的用途,所以我们更关注的是由内部函数形成的闭包。 写在前面 本文尝试模仿 The Little Schema 的风格,介绍 JavaScript 的闭包。本文同时也是我学习 JavaScript 闭包的一次总结。欢迎一起讨...

    Heier 评论0 收藏0
  • javascript闭包介绍

    摘要:下面这个例子就是闭包,函数能够访问到不在其代码块里的变量。然而事实恰恰相反,唯一的解释就是是一个闭包。性能问题执行一次,就会重新构造两个函数。正确的做法应该是参考资料深入理解闭包学习闭包阮一峰 概念 闭包(closure)是一个拥有任意变量以及绑定这些变量的环境(environment)的表达式(一般来说是就是function) A closure is an expression (...

    weij 评论0 收藏0
  • 掌握Javascript面试:什么是闭包

    摘要:我的意思是大多数称职的面试官会问你什么是闭包,并且在大多数时候你回答错误将失去这份工作。在闭包的范围内定义的任何公开方法都是特权的。使对象的数据私有化并不是闭包的唯一用途。 文章来源于:https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-closure-b2f0d2152b36 在J...

    jifei 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<