zoukankan      html  css  js  c++  java
  • 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/

  • 相关阅读:
    【线程退出】linux线程退出的几个函数
    Apache Doris编译安装记录
    你所不知道的java编程思想
    thinking in java知识小记(一)
    一个程序员的修炼之路
    解决linux不能使用chmod更改权限的问题
    centos6.5配置无线网络
    ubuntu16.04 server安装小记
    vim的基本使用方法
    微信之父张小龙经典演讲164页PPT:《微信背后的产品观》
  • 原文地址:https://www.cnblogs.com/jack2013/p/4511680.html
Copyright © 2011-2022 走看看