JS中的this變量使用詳解


JavaScript中this的使用 

在JavaScript中this變量是一個令人難以摸清的關鍵字,this可謂是非常強大,充分了解this的相關知識有助於我們在編寫面向對象的JavaScript程序時能夠游刃有余。 

對於this變量最要的是能夠理清this所引用的對象到底是哪一個,也許很多資料上都有自己的解釋,但有些概念講的偏繁雜。而我的理解是:首先分析this所在的函數是當做哪個對象的方法調用的,則該對象就是this所引用的對象。 

  • 例子1
  • var obj = {}; 
    
    obj.x = 100; 
    
    obj.y = function(){ alert( this.x ); }; 
    
    obj.y(); //彈出 100 

    這段代碼非常容易理解,當執行 obj.y() 時,函數是作為對象obj的方法調用的,因此函數體內的this指向的是obj對象,所以會彈出100。

  • 例子2

    var checkThis = function(){ 
    
    alert( this.x); 
    
    }; 
    
    var x = 'this is a property of window'; 
    
    var obj = {}; 
    
    obj.x = 100; 
    
    obj.y = function(){ alert( this.x ); }; 
    
    obj.y(); //彈出 100 
    
    checkThis(); //彈出 'this is a property of window' 

    這里為什么會彈出 'this is a property of window',可能有些讓人迷惑。在JavaScript的變量作用域里有一條規則“全局變量都是window對象的屬性”。當執行checkThis() 時相當於window.checkThis(),因此,此時checkThis函數體內的this關鍵字的指向變成了window對象,而又因為window對象又一個x屬性('thisis a property of window'),所以會彈出 'thisis a property of window'。 

    上面的兩個示例都是比較容易理解的,因為只要判斷出當前函數是作為哪個對象的方法調用(被哪個對象調用)的,就可以很容易的判斷出當前this變量的指向。 

    this.x 與apply()、call() 

    通過call和apply可以重新定義函數的執行環境,即this的指向,這對於一些應用當中是十分常用的。 

  •  例子3 call();

    function changeStyle( type , value ){ 
    
    this.style[ type ] = value; 
    
    } 
    
    var one = document.getElementByIdx( 'one' ); 
    
    changeStyle.call( one , 'fontSize' , '100px' ); 
    
    changeStyle('fontSize' , '300px'); //出現錯誤,因為此時changeStyle中this引用的是window對象,而window並無style屬性。 

    注意changeStyle.call()中有三個參數,第一個參數用於指定該函數將被哪個對象所調用。這里指定了one,也就意味着,changeStyle函數將被one調用,因此函數體內this指向是one對象。而第二個和第三個參數對應的是changeStyle函數里的type和value兩個形參。最總我們看到的效果是Dom元素one的字體變成了20px

  • 例子4:apply() 
    function changeStyle( type , value ){ 
    
    this.style[ type ] = value; 
    
    } 
    
    var one = document.getElementByIdx( 'one' ); 
    
    changeStyle.apply( one , ['fontSize' , '100px' ]); 
    
    changeStyle('fontSize' , '300px'); //出現錯誤,原因同示例三 

    apply的用法和call大致相同,只有一點區別,apply只接受兩個參數,第一個參數和call相同,第二個參數必須是一個數組,數組中的元素對應的就是函數的形參。 

    無意義(詭異)的this用處 

  • 例子5
    var obj = { 
    
    x : 100, 
    
    y : function(){ 
    
    setTimeout( 
    
    function(){ alert(this.x); } //這里的this指向的是window對象,並不是我們期待的obj,所以會彈出undefined 
    
    , 2000); 
    
    } 
    
    }; 
    
    obj.y(); 

    如何達到預期的效果 

  • var obj = { 
    
    x : 100, 
    
    y : function(){ 
    
    var that = this; 
    
    setTimeout( 
    
    function(){ alert(that.x); } 
    
    , 2000); 
    
    } 
    
    }; 
    
    obj.y(); //彈出100 
  • 事件監聽函數中的this 
    var one = document.getElementByIdx( 'one' ); 
    
    one.onclick = function(){ 
    
    alert( this.innerHTML ); //this指向的是one元素,這點十分簡單.. 
    
    }; 

    注意:js中的全局變量都會動態添加到Window 的實例 window,作為其屬性。 

    this是js的一個關鍵字,隨着函數使用場合不同,this的值會發生變化。但是總有一個原則,那就是this指的是調用函數的那個對象。

  • 純粹函數調用
    function test() { 
    this.x = 1; 
    alert(x); 
    } 
    test(); 

    其實這里的this就是全局變量。看下面的例子就能很好的理解其實this就是全局對象Global。

    var x = 1; 
    function test() { 
    alert(this.x); 
    } 
    test();//1 
    
    var x = 1; 
    function test() { 
    this.x = 0; 
    } 
    test(); 
    alert(x);//0 

    2、作為方法調用,那么this就是指這個上級對象。 

  • function test() { 
    alert(this.x); 
    } 
    
    var o = {}; 
    o.x = 1; 
    o.m = test; 
    o.m(); //1 

    3、作為構造函數調用。所謂構造函數,就是生成一個新的對象。這時,這個this就是指這個對象

    function test() { 
    this.x = 1; 
    } 
    var o = new test(); 
    alert(o.x);//1 

    4、apply調用

 this指向的是apply中的第一個參數。 

var x = 0; 
function test() { 
alert(this.x); 
} 

var o = {}; 
o.x = 1; 
o.m = test; 
o.m.apply(); //0 
o.m.apply(o);//1 

當apply沒有參數時,表示為全局對象。所以值為0。

  • 特殊例子詳解,不同情況不同指代
    var name = "The Window"; 
    var object = { 
    name : "My Object", 
    getNameFunc : function(){
    var func = object.getNameFunc(); 
    alert( func() ); 
     
               

     

    return function(){ 
    return this.name; 
    }; 
    } 
    }; 

    alert(object.getNameFunc()());原因是js的this是動態決定的,和你調用方式有直接關系。 

    簡單說如果你調用一個函數的時候使用“對象.函數名”的方式,那么this就是這個.(點)之前的對象,否則是window。 
    比如你在調用object.getNameFunc()的時候getNameFunc函數體中的this是剛聲明的object。如果你寫成

    var func = object.getNameFunc; 
    func(); 

    這時候getNameFunc函數體中的this是window,雖然是同一函數調用方式的不同決定了this的不同。 
    同樣的道理,object.getNameFunc()返回的是一個函數引用,加一個括號就是讓函數執行。其實相當於如下代碼 

    var func = object.getNameFunc(); 
    alert( func() ); 

    函數前沒有“對象.”這種形式,所以執行函數時候this是window,結果就很明顯了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM