javascript 函數執行上下文


在js里,每個函數都有一個執行的上下文,我們可以通過this來訪問。

如:

全局函數

function test(){

var local = this;

}

我們發現local等於window(dom根對象),也就是說全局函數實際上是window的一個屬性。

同理全局變量也是如此。

比如 var name = ‘phil’; 我們可以通過window[‘name’]或者window.name 來訪問。

 

而當函數是某一個對象的屬性的時候,該函數的上下文就是該對象。

var student = {};

student.age = 20;

student.getAge = function(){

return this.age;

}

 

當有函數嵌套的時候,事情就變得稍微復雜點了。

var seq = [1,2,3,4];

for(var i in seq){

var name = ‘phil’ + i;

window.setTimeout(function(){

        $('p’).apend(name);

},i*1000)

}

有人可能認為輸出是phil1phil2phil3phil4,實際上結果是phil4phil4phil4phil4

因為函數window.setTimeout(實際上我們常常會省略掉window)的上下文實際上是window,而函數體中的name實際上就是window.name

他的值就是最后一次循環后的值phil4。

 

那如果我們需要的結果是phil1phil2phil3phil4那該怎么寫:

var seq = [1,2,3,4];

for(var i in seq){

var name = ‘phil’ + i;

var obj = {};

obj.name = name;

obj.setTimeout  = function(){

        var local = this;                  // 該方法是對象obj的屬性方法,所以this就是obj

window.setTimeout(function(){

        $('p’).apend(local.name);        // 此處千萬不可以用this,因為此處的this實際上是window。

},i*1000)

}

}

call和apply通常用來修改函數的上下文,函數中的this指針將被替換為call或者apply的第一個參數

//定義一個人,名字為jack
var jack = {
    name : "jack",
    age : 26
}
 
//定義另一個人,名字為abruzzi
var abruzzi = {
    name : "abruzzi",
    age : 26
}
 
//定義一個全局的函數對象
function printName(){
    return this.name;
}
 
//設置printName的上下文為jack, 此時的this為jack
print(printName.call(jack));
//設置printName的上下文為abruzzi,此時的this為abruzzi
print(printName.call(abruzzi));
 
print(printName.apply(jack));
print(printName.apply(abruzzi));

 

只有一個參數的時候call和apply的使用方式是一樣的,如果有多個參數:

function setName(value){

this.name = value;

}

 

setName.apply(jack, ["Jack Sept."]);
print(printName.apply(jack));
 
setName.call(abruzzi, "John Abruzzi");
print(printName.call(abruzzi));


免責聲明!

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



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