• JS闭包


    问题1:闭包

    考虑下面的代码:

    var nodes = document.getElementsByTagName('button');
    for (var i = 0; i < nodes.length; i++) {
       nodes[i].addEventListener('click', function() {
          console.log('You clicked element #' + i);
       });
    }

    请问,如果用户点击第一个和第四个按钮,控制台上会输出什么?为什么?

    答案

    上面代码的目的在于检测JavaScript的一个重要概念:闭包。对于每一个JavaScript开发者来说,如果你想在网页中编写5行以上的代码,那么准确理解和恰当使用闭包是非常重要的。如果你想开始学习或者只是想简单地温习一下闭包,那么我强烈建议你去阅读这个教程:Colin Ihrig 写的JavaScript Closures Demystified 。

    好了,回到上面的代码。控制台会输出两次You clicked element #NODES_LENGTH,其中#NODES_LENGTH等于nodes的结点个数。由于闭包中变量的值不是静态的,i的值并不是添加click事件处理器时的值(比如,当给第一个button添加click事件处理器时i为0,给第二个添加时i为1)。当for循环结束时,变量i的值等于nodes的长度。因此事件被执行时,控制台会输出变量i当前的值,即等于nodes的长度。

    问题2:闭包

    修复上题的问题,使得点击第一个按钮时输出0,点击第二个按钮时输出1。

    答案

    有多种办法解决这个问题,下面我给出其中的两种。

    第一个解决方案要用到一个IIFE来创建另外一个闭包,从而得到所希望的i的值。相应的代码如下:

    var nodes = document.getElementsByTagName('button');
    for (var i = 0; i < nodes.length; i++) {
       nodes[i].addEventListener('click', (function(i) {
          return function() {
             console.log('You clicked element #' + i);
          }
       })(i));
    }

    另一个解决方案不使用IIFE,而是将函数移到循环的外面,代码如下:

    function handlerWrapper(i) {
       return function() {
          console.log('You clicked element #' + i);
       }
    }
     
    var nodes = document.getElementsByTagName('button');
    for (var i = 0; i <nodes.length; i++) {
       nodes[i].addEventListener('click', handlerWrapper(i));
    }

    来源:http://web.jobbole.com/81785/

  • 相关阅读:
    mysql 严格模式 Strict Mode
    PHP中NULL和‘'的区别
    nginx 出现413 Request Entity Too Large问题的解决方法
    mysql 转换NULL数据方法
    mysql大小写敏感配置
    mysql导入大批量数据出现MySQL server has gone away的解决方法
    mysql函数concat与group_concat使用说明
    Linux下aMule安装教程
    四、YOLO-V1原理与实现(you only look once)
    tf.cast(ndarray,dtype)
  • 原文地址:https://www.cnblogs.com/jack2013/p/4511680.html
Copyright © 2020-2023  润新知