JavaScript this指針

this指針,在Java EE等開發語言中叫做“上下文對象”,但是在JavaScript中情況完全不同,不能把Java EE中對this的理解帶到JavaScript中來。
言歸正傳,在JavaScript中,this代表函數運行時,自動生成的一個內部對象,只能在函數內部使用。也就是說this跟函數的聲明沒有任何關係,只有在函數或者方法被調用時才知道this的值。this關鍵字會根據環境變化,但是它始終代表的是調用當前函數的那個對象,記住一點:誰調用這個函數或方法,this關鍵字就指向誰。在JavaScript中函數的調用模式大致分爲以下4種:
1、函數調用模式
即一個函數並非某個對象的屬性時,那麼它就是被當做函數來調用的。在此種模式下,this被綁定爲全局對象,在瀏覽器環境下就是window對象。例

function sayName() {
    this.name = "tang";
    console.log(this.name);
}
sayName();//tang

由於this===window對象,上面的寫法等同於:

var name = "tang";
function sayName() {
    console.log(this.name);
}
sayName();//tang

注意和下面的寫法區分

function sayName() {
    var name = "tang";
    console.log(this.name);
}
sayName();////ReferenceError資源不存在錯誤(由於在window對象不存在name屬性)

2、方法調用模式
當函數是某個對象的屬性時,它就可稱爲這個對象的方法。當一個方法被調用時,this被綁定到這個對象上。例

var name = "window";
var obj = {
    name: "obj",
    sayName: function() {
        console.log(this.name);
    }
};
obj.sayName();  //obj

此時的this指向obj對象
注意和下面的寫法區分

var name = "window";
var obj = {
    name: "obj",
    sayName: function() {
        console.log(this.name);
    }
};
var ss = obj.sayName;  
ss();   //window

這種情況相當於在全局作用域調用,是函數調用而不是方法調用!
3、構造函數模式
當函數被作爲構造函數調用時(即通過函數new新的函數實例對象),this被綁定到新創建的函數對象上。例

function Obj() {
    this.name = "kxy";
}
var person = new Obj();
console.log(person.name);   //kxy

4、call/apply調用模式
JavaScript中,函數可以通過call和apply方法在特定的執行環境中自調,區別在於call傳遞多個參數,apply傳遞參數數組。不管怎麼樣,這兩個函數的第一個參數都是特定的執行環境。下面以apply爲例

var name = "window";
var person = {
    name: "kxy"
};
function sayName() {
    console.log(this.name);
}
sayName();    //window
sayName.apply(person);   //kxy(傳遞person作爲執行環境)
sayName.apply();    //window(不傳參數是默認的執行環境是全局環境window)

除了上面常見的4中函數調用模式外,還有幾種特殊調用,this均指向全局變量window
1、匿名函數調用

var name = "Bob";  
var nameObj ={  
     name : "Tom",  
     showName : function(){  
         alert(this.name);  
     },  
     waitShowName : function(){  
         !function(__callback){
            alert(this.name); 
        }();  
     }  
 };  
 nameObj.showName();   //Tom
 nameObj.waitShowName();  //Bob

2、setTimeout和setInterval

var name = "Bob";  
var nameObj ={  
    name : "Tom",  
    showName : function(){  
        alert(this.name);  
    },  
    waitShowName : function(){
        setTimeout(function(){
            this.showName();
        }, 1000);
    }
}; 

 nameObj.waitShowName();  //Bob

如果想輸出期望值,不凡先保存this的值

var name = "Bob";  
var nameObj ={  
    name : "Tom",  
    showName : function(){  
        alert(this.name);  
    },  
    waitShowName : function(){
        var that = this;
        setTimeout(function(){
            that.showName();
        }, 1000);
    }
}; 

 nameObj.waitShowName();  //Tom

無論JavaScript表達式多複雜,嵌套調用多少次,都離不開以上提到的幾種情況,只要層層分析,總能得到期望值!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章