定時器中的this指向問題

原文地址:http://www.zhangyunling.com/?p=134


看例子:代碼中中的兩個setTimeout執行後的結果分別是什麼?

  
<span style="font-size:18px;"> var a = 1;
    function B(){
        var a = 2;
        setTimeout("C()",1000);
        setTimeout(C,2000);
        function C(){
            alert("a="+a);
        }
    }
    function C(){
        alert("a="+a);
    }
    B();
</span>


測試一下也就知道了,分別爲1和2,因爲setTimeout是把後面執行的方法,第一種寫法,只會查找全局變量中,是否有A函數,而第二種寫法,會優先查找當前作用域中是否有A函數,如果局部沒有的話,則順序查找到全局作用域中

有一種情況,是說,計時器內部調用的函數的this指向,是指向window的,這裏可以說有錯,也可以說沒錯,看一個例子:假設給id=test的一個元素綁定一個click事件。查看其中的this的值。

   
<span style="font-size:18px;">document.getElementById("test").onclick = function(){
        alert(this); //指向觸發該事件的元素對象
        setTimeout("A()",1000); //這裏調用指向window
    }

    function A(){
        alert(this);
    }</span>



這裏就不考慮在IE8-的瀏覽器了。

按照最初寫的兩個計時器的例子,在寫出如下的代碼:

  
<span style="font-size:18px;"> document.getElementById("test").onclick = function() {
        alert(this); //指向觸發該事件的元素對象
        setTimeout(A,1000); ////這裏依然指向window
        function A(){
            alert(this);
        }
    };
    function A(){
        alert(this);
    }</span>



爲什麼?不是按理說,這裏應該是調用的內部的A方法嗎?爲什麼this卻是指向的window?

有一個不確定的想法是:當調用了計時器時,會把當前作用域中的方法,內部的this指向window對象了。而且僅僅是修改了方法內部的this指向,如果有私有變量的取值,依然按照原函數所在的位置,根據作用域,進行取值。

可以這麼證明一下:

 
<span style="font-size:18px;">   var a = 1;
    document.getElementById("test").onclick = function() {
        alert(this);
        var a = 123;
        setTimeout(A,1000);
        function A(){
            alert("a="+a);
            alert(this);
        }
    }
    function A(){
        alert("a="+a);
        alert(this);
    }</span>



this的指向是和上面一個實例相同的,而alert中的a變量的取值,卻是優先獲取局部作用域中的值。

當然啦,這裏如果把計時器中的調用方法,更換一下,那結果就不相同了哦。

  
<span style="font-size:18px;"> var a = 1;
    document.getElementById("test").onclick = function() {
        alert(this);
        var a = 123;
        setTimeout("A()",1000);
        function A(){
            alert("a="+a);
            alert(this);
        }
    }
    function A(){
        alert("a="+a);
        alert(this);
    }</span>



這裏,有興趣的可以試試吧,說到這裏,也發現,雖然使用計時器會強制把調用函數的內部的this指向改變成指向window的,但是對於作用域鏈的影響卻只有寫法不同帶來的影響。即:setTimeout("A()",1000);和setTimeout(A,1000);的不同。當然對於第二種寫法,我們可以使用call和apply強行改變A內部this的指向,
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章