P39也,讲闭包的。//糟糕的例子
var add_the_handlers = function(nodes){
    var i;
    for (i = 0; i < nodes.length; i += 1){
      nodes[i].onclick = function(e){
        alert(i);//这里到底想干什么? 看下边的更好的例子,是想输出e,这里i是啥意思?
      }
    }
};
//更好的例子
var add_the_handlers = function (nodes){
  var i;
  for(i = 0; i<nodes.length;i+=1){
    nodes[i].onclick = function(i){
      return function(e){
        alert(e);
      };
    }(i);
  }
};这个更好的例子,(i)是执行的哪个函数?是return回来的函数?如果想立即执行一个函数不是要将函数用括号括起来 (function(){})();这样吗?另外chrome用console.dir 列出一个对象,有一个__proto__的属性,不知道这个是啥。
还有firebug的控制台不能用,报这样的错误,是什么原因?
uncaught exception: _FirebugCommandLine init failed in about:blank because TypeError: window.loadFirebugConsole is not a function
Firebug cannot find firebug-CommandLineAttached document.getUserData , its too early for command line Window about:blank

解决方案 »

  1.   

    /**
     * 最优雅的解决方法
     */
    var add_the_handlers = function (nodes)
    {
    function Click(i)
    {
    nodes[i].onclick = function(){alert(i)}
    } for(var i = 0; i<nodes.length; i++)
    new Click(i);
    };
      

  2.   

    /**
     * 最优雅的解决方法
     *
     * 此处共3个function
     *   add_the_handlers:
     *     最外层闭包体,里面共享nodes参数
     *   Click:
     *     此function并不直接调用,
     *     直接调用则共享i变量。
     *     而用new创建一个实例,每个实例都有独立的闭包体
     *   一个匿名函数:
     *     属于Click闭包内。Click被new之后这个匿名函数独享i变量
     */
    var add_the_handlers = function (nodes)
    {
        function Click(i)
        {
            nodes[i].onclick = function(){alert(i)}
        }    for(var i = 0; i<nodes.length; i++)
            new Click(i);
    };
      

  3.   

    当然也可以忽略Click这个名字,不过必须只能这样写:
    /**
     * Add Click
     */
    var add_the_handlers = function (nodes)
    {
    for(var i = 0; i<nodes.length; i++)
    {
    new function(i)
    {
    nodes[i].onclick = function(){alert(i)};
    }(i)
    }
    };
      

  4.   

    lS    new   不应出现, 将浪费效率
      

  5.   

    这个更好的例子,(i)是执行的哪个函数?是return回来的函数?如果想立即执行一个函数不是要将函数用括号括起来 (function(){})();这样吗?
    执行的是return回来的函数,不是立马执行,是调用方法的时候才执行。
      

  6.   

    new是必须的。不用new是无法新建一份独立的比包体的。除非用return function的形式,但不宜理解。
      

  7.   

    刚才说错了。new不用是可以的。只要执行了外围闭包就可以了。
      

  8.   

    不好意思下午发的是以前保存的代码。其实这个问题很简单的。
    var add_the_handlers = function (nodes)
    {
    for(var i = 0; i<nodes.length; i++)
    {
    +function(i)
    {
    nodes[i].onclick = function(){alert(i)};
    }(i)
    }
    };
      

  9.   

    原来是我理解错这个例子的目的了。查了勘误表,这个“更好的例子”里的 alert(e)应该改为alert(i), 而第一个糟糕的例子是错误实现。大家怎么没有看我后边的问题的
      

  10.   

    这个function前的加号是什么意思呢?还有这个(i)是为了执行哪个函数的?
      

  11.   

    其实这个是作用域的问题.只要理解了js的作用域的问题就能够很好的理解很多问题(包括所谓的闭包)我也是最近刚刚理解的,不知道理解的对不对.(个人意见,仅作参考)"js中的函数是通过词法来划分作用域的,而不是动态的划分作用域的."(引自:权威)为了更好的理解这句话,我在网上找了一段代码var x=0;
    function f(){
            alert(x)
    }function f2(){
            var x=1;
            f()
    }f2();
      

  12.   

    狗屁最优雅的解决方法 [/code][code=JScript]
    var add_the_handlers = function(nodes){
    var len = nodes.length;
        for (var i = 0; i < len; i++){
         (function(obj, index) {
       obj.onclick = function(e){
             alert(index);
    }
         })(nodes[i], i);
        }
    };
      

  13.   


    这个比较容易理解。
    谁能解释一下11楼的 +function 是什么意思啊。
    没有这个加号还真不行。
      

  14.   


    +function(){} 是一个表达式 这样里面的function(){}就变成了一个匿名函数()是调用函数的运算符
      

  15.   

    +function(){...}()

    (function(){...})()
    是一样的
    是为了让解析器识别为匿名函数并执行之
    用其它操作符也可以,比如
    -function(){...}()
      

  16.   

    <ul id="box">
    <li>111111111111</li>
    <li>2222222222222222</li>
    <li>333333333333333333</li>
    </ul>
    <script>var add_the_handlers = function (nodes){
      var i;
      for(i = 0; i<nodes.length;i+=1){
        nodes[i].onclick = function(i){//定义onclick动作匿名函数
          return function(){
            alert(i); 读取返回匿名函数外参数i,并弹出。
          };
        }(i); //把i当参数传进去
      }
    };var nodes = document.getElementById('box').getElementsByTagName('li');add_the_handlers(nodes);这样写才是对的。