javascript - 为什么此js函数里只能用this才能实现?
大家讲道理
大家讲道理 2017-04-11 12:06:53
[JavaScript讨论组]
function highlightRows() {
    if(!document.getElementsByTagName) return false;
    var tables = document.getElementsByTagName("table");
    for(var i=0;i

为什么注释的那两行不行,非要用this呢,这里this不是应该就是指代rows[j]么?

大家讲道理
大家讲道理

光阴似箭催人老,日月如移越少年。

全部回复(8)
PHPz

变量作用域问题

假设
rows.length = 9
最后一次for执行完毕的时候
j = 9

function() {
  rows[j].style.fontWeight="normal";
}

所有的匿名函数里面 j = 9,
绑定事件的时候j还不是9,执行的时候j已经全部是都是9了

也就是你绑定的所有事件都只对最后一个生效。
解决方法是用闭包

(function(j){
  rows[j].onmouseout=function() {
    rows[j].style.fontWeight="normal";
  }
})(j);
伊谢尔伦

因为j不是你想象的j

黄舟

你的事件绑定的function,可以拿到rows[j],但是等到这个function执行的时候,for循环早结束了,你的j拿到的都是循环后的值。。。所以设置的都是最后一项吧

伊谢尔伦

因为函数定义时所处的环境和函数运行时所处的环境(里面的东西),往往是不同的。
尤其是像题目中那样,存在异步的情况下。

简单地说,你那个回调函数被调用的时候,可能是1个小时以后了,那时候的j早就与注册时的j不同了。

PHP中文网

代码

for(var j =0;j<rows.length;j++){
            rows[j].onmouseover=function(){
                this.style.fontWeight="bold";
            }
            rows[j].onmouseout=function() {
                this.style.fontWeight="normal";
            }
        }

执行时,给当前循环内rows[j]也就是tr元素绑定事件,绑定后mouseover触发即会执行匿名函数。
假设你table有3行,当该段代码执行结束后,j已经变成3,此时不能够拿到正确的tr了呐。

 //rows[j].style.fontWeight="bold"; //这样无效

这个rows[j]还真不是this呢。

天蓬老师

for(var j =0;j<rows.length;j++){

      var rows[j].index=j;
        rows[j].onmouseover=function(){
            rows[this.index].style.fontWeight="bold";
        }
        rows[j].onmouseout=function() {
           rows[this.index].style.fontWeight="normal";
        }
    }
巴扎黑

骚年,你还没弄明白JavaScript函数的创建上下文执行上下文的区别。

不需要看代码,你直接搜索一下两个概念就可以了,顺便你也就弄明白闭包、执行环境对象、作用域链的问题了。

我这个回答虽然简单,但我觉得切中要害。

高洛峰
// This doesn't work like you might think, because the value of `i` never
// gets locked in. Instead, every link, when clicked (well after the loop
// has finished executing), alerts the total number of elements, because
// that's what the value of `i` actually is at that point.
//以下的代码运行起来将不会像你想象中的那样,因为其中的‘i’值(在每一次循环中)没有被锁定。
//取而代之当你点击每一个连接的时候(就是其中的循环已经结束了),浏览器总会去提醒’总元素个数‘
//因为那就是’i‘的在这个时候的确切值。
  
var elems = document.getElementsByTagName( 'a' );
    
for ( var i = 0; i < elems.length; i++ ) {
    
   elems[ i ].addEventListener( 'click', function(e){
      e.preventDefault();
      alert( 'I am link #' + i );
   }, 'false' );
    
}
    
// This works, because inside the IIFE, the value of `i` is locked in as
// `lockedInIndex`. After the loop has finished executing, even though the
// value of `i` is the total number of elements, inside the IIFE the value
// of `lockedInIndex` is whatever the value passed into it (`i`) was when
// the function expression was invoked, so when a link is clicked, the
// correct value is alerted.
//以下的代码可以工作,因为有自调用函数(IIFE)的缘故,
//’i‘的值被锁定成为函数的传入参数’lockedInIndex‘,当循环运行完毕的时候,
//尽管’i‘的值还是总元素的个数,但是在IIFE中,
//’lockedInIndex‘的值永远是该函数表达式被调用的时候所传入的’i‘值。
//所以当一个连接被点击的时候,可以提示出正常的值。
    
var elems = document.getElementsByTagName( 'a' );
   
for ( var i = 0; i < elems.length; i++ ) {
    
  (function( lockedInIndex ){
    
    elems[ i ].addEventListener( 'click', function(e){
      e.preventDefault();
      alert( 'I am link #' + lockedInIndex );
    }, 'false' );
  
  })( i );
    
}

  
  

以上内容全文引用自Ben Alman Immediately-Invoked Function Expression 作者为Ben Alman

翻译是我自己写的,我也在学这些内容,碰巧看到了就引用一下,恩,应该不会被打。
特别鸣谢:Special Thanks: Ben Alman

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号