首页 > JS中this的问题

JS中this的问题

HTML部分:

    <ul id="ul">
        <li>hello</li>
        <li>yeah</li>
        <li>yes</li>
        <li>nope</li>
    </ul>

JS部分:

    var ul = document.getElementById('ul');
    var lis = ul.getElementsByTagName('li');
    for(var i = 0, len = lis.length; i < len; i++)
    {
        lis[i].onclick = function(){
            ***this***.style.fontSize = '30px';
        }
    }

为什么把this.style.fontSize的this改成lis[i]就没有点击li后字体变大的效果了呢?
这里的this难道不是指的是对象lis[i]吗?


因为onclick是一个异步的事件,当事件触发的时候循环已经执行完了,所以这个时候i已经是lis.length了,不行你可以打印一下看。你可以通过闭包的方式了解决这个问题

 for(var i = 0, len = lis.length; i < len; i++)
 {
     (function(i){
         lis[i].onclick = function(){
            lis[i].style.fontSize = '30px';
        }
     })(i);      
 }

简单的说就是谁调用了函数,函数的this就是谁。
所以dom的click事件触发了函数,this就是这个dom
所以可以通过foo.func.call(bar)改变this指向bar。。


this是事件监听器函数声明时的lis[i],但不是事件监听器函数调用时的lis[i]。

这样改一下:

list[i].click = (function(j) {
    return function() {
        list[j].style.fontSize = '30px';
    };
})(i);

就可以把声明时的i保持到调用时了。


改成 lis[i] ,循环完毕的时候,闭包中的i始终等于lis.length 也就是4
onclick的时候,lis[i]就报异常了, 具体你可以检查一下console,或者在onclick里输出一下 i 的值


this确实是指向点击的那个DOM对象,但lis[i]不是了,i是指向上一层闭包的一个引用,当onclick的事件处理发生的时候,i已经完成了循环遍历,它的值是len。
具体请参阅javascript闭包机制方面的内容。


this所指向的对象需要具体看其执行的环境,如果是在全局环境中执行,它代表的是window,如果是在类中执行则代表当前类,当然如果通过callapply调用还可以为this指定对象.


闭包 不信你点击最后一个li

【热门文章】
【热门文章】