• 探究JavaScript闭包


    什么是JavaScript闭包?

    刚开始知道这个词,就误以为是自动执行的匿名函数块。
    比如说+function(){}();
    然而并不是,那么请看下面的例子:

    function init() {
      var name = "initial";
      function displayName() {//displayName() is the inner function, a closure
        alert(name);    
      }
      displayName();    
    }
    init();

    displayname()是闭包吗?函数内部访问函数成员局部属性的方法?

    This is an example of lexical scoping: in JavaScript, the scope of a variable is defined by its location within the source code (it is apparent lexically) and nested functions have access to variables declared in their outer scope

    这是一个词法域的例子:Javascript中,变量的作用域由他所在的代码区域(明显的词法上的),和可以访问外部作用域的嵌套方法组成。

    闭包Closure

    再看这个例子:

    function makeFunc() {
      var name = "Mozilla";
      function displayName() {
        alert(name);
      }
      return displayName;
    }
    
    var myFunc = makeFunc();
    myFunc();

    What’s different — and interesting — is that the displayName() inner function was returned from the outer function before being executed.
    不同并且有趣的地方是:内部方法displayName在函数外面被return出来,还是在执行之前。
    那么可以大胆的说:myFunc就是一个闭包。

    A closure is a special kind of object that combines two things: a function, and the environment in which that function was created.
    闭包就是一个包含了两个东西的特殊对象:一个方法和创建这个方法的环境。
    再看看一个例子 :

    function makeAdder(x) {
      return function(y) {
        return x + y;
      };
    }
    
    var add5 = makeAdder(5);
    var add10 = makeAdder(10);
    
    console.log(add5(2));  // 7
    console.log(add10(2)); // 12

    显然add5和add10各自都有各自的环境,所持有的变量是不同的。
    看一个闭包引起的错误,比较难理解透。

    function showHelp(help) {
      document.getElementById('help').innerHTML = help;
    }
    
    function setupHelp() {
      var helpText = [
          {'id': 'email', 'help': 'Your e-mail address'},
          {'id': 'name', 'help': 'Your full name'},
          {'id': 'age', 'help': 'Your age (you must be over 16)'}
        ];
    
      for (var i = 0; i < helpText.length; i++) {
        var item = helpText[i];
        document.getElementById(item.id).onfocus = function() {
          showHelp(item.help);
        }
      }
    }
    
    setupHelp();

    如果有三个输入框,那么每个框点击都会导致#help的内容变成Your age (you must be over 16)。
    原因是:赋值给document.getElementById(item.id).onfocus
    的function是个闭包函数:,这里循环创建了三个闭包,但是他们共享了同一个外部作用域,也就是setupHelp,那么自然循环结束的时候,onfocus 里面就是指向了数据的最后一个元素。
    这些话并不太容易让人相信。

    我debug跟踪了一下:
    循环走完的时候,onfocus function(){}里面 item 的id已经是’age’,help是
    ‘Your age (you must be over 16)’

    三个input对象都是onfocus绑定了同一个闭包(等同于同一个,环境里变量和函数行为都一样)。

    闭包性能

    通常一个函数执行完毕之后它内部的局部变量就已经不能再访问了。
    而闭包需要维持他所被创建时的作用域环境,过分使用闭包对速度上的性能和内部的消耗是有影响的。没必要的时候不要使用闭包。

    本文引用自:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

  • 相关阅读:
    JQ-动画合集(ing...)
    CSS-各种cs样式之浏览器兼容处理方式汇总大全(更新中...)
    CSS-用伪元素制作小箭头(轮播图的左右切换btn)
    CSS-垂直|水平居中问题的解决方法总结
    JS-自制提速小工具:开发页面时需要按比例计算宽高值的快速计算器
    canvas-渐变文字
    HTML-一个网页的头部的大概框架(完善ing)
    JS-面向对象
    CSS-border属性制作小三角
    JS事件-事件处理程序-笔记总结ing...
  • 原文地址:https://www.cnblogs.com/slankka/p/9158527.html
Copyright © 2020-2023  润新知