2014-02-17 23 views
1

我對節點模塊中this的行爲非常困惑。下面是相關片段:「this」在函數中的某個對象的函數中

module.exports = function(environment) { 
    var config = require('./config'); 

    return { 
     config: config, 
     agencies: ["string1", "string2"], 

     getRoutes: function(callback) { 
      var API = "/api/route/"; 
      this.agencies.forEach(function(agency) { 
       console.log(this.config); //Returns undefined?? 
      } 
     } 
    } 
} 

望着MDN documentation on this說,在以物體的功能的this指對象。然後我會期待console.log(this.config)引用require'd config模塊。相反,目前尚不清楚this最終是指什麼,除了它沒有「config」屬性。

顯然有一個範圍正在改變,但我不知道在哪裏。 forEach?我試圖只是console.log(this),但我收回了一個我無法破譯的巨大對象。

我不明白爲什麼配置超出此功能的範圍。這是怎麼回事?

+0

裏面的'forEach'功能,你現在是在不同的上下文。所以,「這個」是不同的。 –

+3

**每個**函數調用都會在被調用的函數內建立一個'this'的值,包括對'.forEach'處理函數每次迭代的調用。 – Pointy

+1

注意:某些迭代器函數(例如['jQuery.each'](https://api.jquery.com/jQuery.each/))將建立一個自定義'this'上下文,例如被迭代的項目。但是,它仍然是一個*不同的函數執行上下文。 – user2864740

回答

7

這是undefined,因爲函數中默認值this是全局對象。

爲了修正它,通過將對象作爲第二個參數.forEach()

this.agencies.forEach(function(agency) { 
    console.log(this.config) 
}, this) 
// ^---sets the `this` value 

方式this作品是,它是由函數是如何稱爲確定。因爲.forEach()不知道回調中的this值是什麼,所以它將其保留爲默認值(全局對象)或undefined(嚴格模式下)。

通過傳遞第二個參數,您告訴它手動將this設置爲您提供的任何內容。

它是如何實現這個功能的(或者你怎麼做到的)就是使用函數的.call().apply()方法調用函數。

myFunction.call({foo:"bar"}); 

現在myFunction將與設置爲它的this{foo:"bar"}對象被調用。

+0

我欠你一個upvote,但沒有代表。這是一個很好的答案,有一個更正和解釋。 – ABMagil

+0

@ABMagil:不是問題。很高興幫助。 –

+0

一個請求 - 你能否在你的示例代碼註釋中說明「設置'這個'值'是指在函數範圍內設置'this'(假設我理解正確)?一讀時,我不確定你的意思。 – ABMagil

3

上下文切換髮生在循環,因爲裏面我相信這是「機構」

module.exports = function(environment) { 
var config = require('./config'); 

return { 
    config: config, 
    agencies: ["string1", "string2"], 

    getRoutes: function(callback) { 
     var API = "/api/route/"; 
     var self = this; 
     this.agencies.forEach(function(agency) { 
      console.log(self.config); //Returns undefined?? 
     } 
    } 
} 
} 
0

this價值取決於它是如何在函數被調用。

這是它在功能:

function(agency) { 
    console.log(this.config); //Returns undefined?? 
} 

它作爲參數傳遞agencies.forEachagencies是一個數組,所以我們可以看看the documentation

如果thisArg參數提供的forEach,它會通過調用時,用作this值回調。否則,未定義的值將被傳遞以用作其值。

所以thisundefined

根據上述文檔,您可以爲this傳遞不同的值。

this.agencies.forEach( 
     function(agency) { 
      console.log(this.config); //Returns undefined?? 
     }, 
     this 
); 

在這種情況下,你可以使用一個閉合。 config(來自var config = require('./config');)仍然在範圍內。所以只需使用config而不是this.config

1

函數內的this的值取決於創建和調用它的情況。當您使用forEach時,您將傳遞一個匿名函數作爲第一個參數,該參數具有this引用的其自己的塊範圍。

有幾種方法可以控制函數中的this的值。您可以創建在父範圍局部引用,這是通過關閉訪問:

getRoutes: function(callback) { 
     var API = "/api/route/"; 
     var me = this; // local reference to the current scope 
     this.agencies.forEach(function(agency) { 
      console.log(me.config); // accessed via closure 
     }); 
    } 

...你可以bind功能:

getRoutes: function(callback) { 
     var API = "/api/route/"; 
     this.agencies.forEach(function(agency) { 
      console.log(this.config); 
     }.bind(this)) 
    } 

...或者你可以通過上下文第二個參數給forEach,讓引擎綁定範圍內爲您提供:

getRoutes: function(callback) { 
     var API = "/api/route/"; 
     var me = this; 
     this.agencies.forEach(function(agency) { 
      console.log(this.config); 
     }, this); 
    } 

文檔

+0

*「函數內的範圍是指函數本身。」*這是不正確的。在JavaScript中它很少引用函數本身。爲了使其引用該函數,你需要做一些類似'myFunction.call(myFunction);'或'myFunction.func = myFunction; myFunction.func();',這兩者都是非常不尋常的 –

+0

@cookiemonster呃,它可能更好。 –

相關問題