2014-02-25 123 views
2

我已經開始與節點進行試驗,我已經在單個文件內工作。 這是我的代碼的基本原則:的JavaScript模塊模式,這

function Validation(){ 
    this.a = function(){...} 
    this.b = function(){...} 
    return this; 
} 

var validation = Validation(); 

(function(){ 
    models["a"] = { 
     validate: [a, b] 
    } 
}).call(validation); 

這工作完全正常。現在我想將驗證功能移到它自己的文件validation.js中。因此,我將我的代碼更改爲:

/* validation.js */ 
function Validation(){ 
    this.a = function(){...} 
    this.b = function(){...} 
    return this; 
} 

module.exports.Validation = new Validation(); 


/* Main file */ 
var validation = require('./validation'); 

(function(){ 
    models["a"] = { 
     validate: [a, b] 
    } 
}).call(validation); 

當我嘗試運行此代碼時,出現錯誤「ReferenceError:a is not defined」。 我可以通過改變athis.a解決這個問題,但爲什麼它沒有this關鍵字之前的工作?

+0

僅僅是因爲IIFE就是所謂的上下文'validation','a'告訴JS掃描範圍(當前和最多,一直到全局)爲一個名爲'a'的_variable_。 'this.a'告訴JS在上下文對象的原型鏈中查找名爲'a'的_property_,即'Validation'。你可以寫'(function(){validation.a;}());'。 'validation'將被解析爲全局的'var validation',並且正在訪問它的'a'屬性 –

+0

如果你只構造一次驗證對象,爲什麼你會使用一個構造對象呢? – OrangeDog

回答

2

Validation(沒有new關鍵字)不是一個構造函數,所以在它內部使用this來處理全局對象上下文。

試試這個:

function Validation() { 
    return { 
     a: function() {...}, 
     b: function() {...} 
    }; 
} 

或者以其他方式使用module.exports.Validation = new Validation();

除了你的實際問題。你必須使用this.a因爲有出口,可以作爲ab(它與全局對象發生雖然)無局部範圍內的變量。當然,你可以使用withwith (this) models["a"] = {validate: [a, b]})但它是好主意,在所有使用它。因此,答案是,你必須使用this.a

+0

對不起,我其實是在做你喜歡的第二件事。在我簡化的例子中只是一個錯字。 –

+0

你嘗試了第一種方法嗎? – dfsq

+0

是的,但它給出了完全相同的結果。 –

0

你有兩個重大失誤。

module.exports.Validation = Validation(); 

調用函數Validation (沒有新this)和返回的對象導​​出爲Validation

var validation = require('./validation').Validation(); 

調用出口Validation,這是不是一個FUNC而是上面創建的對象。

最有可能的,你要導出的構造,然後用它來構造一個對象?

module.exports = Validation; 
... 
var Validation = require('./validation'); 
var obj = new Validation(); 
+0

我改變了我的帖子,那裏有錯別字。 –

+0

您未能解決實際問題:爲什麼OP需要'this.a'而不是'a' –

+0

實際問題是對模塊工作方式的明顯誤解。瞭解'this'的細節並不有用,因爲它仍然是錯誤的。 – OrangeDog

1

爲什麼它沒有this?很簡單,因爲我在我的評論說:

僅僅是因爲IIFE被稱爲在validation的背景下,但你的a利用告訴JS掃描範圍(當前和,一路到全球)的變量稱爲a
this.a告訴JS在上下文對象的原型鏈中尋找屬性,稱爲a,即Validation

你也許能寫

(function() 
{ 
    models["a"] = { 
     validate: [a, b] 
    }; 
}()); 

validation將通過範圍掃描來解決全球var validation。然後,您只需通過this.a即可訪問a屬性,就像現在一樣。

注:
寫作models["a"]您IIFE不加起來裏面:models是,因爲你的代碼代表,一個暗示全球,這是邪惡的!
這樣看來,models是一個對象,雖然,但我不明白你爲什麼會用括號標記設置屬性,爲什麼不寫:

var models = {a: { validate: [this.a, this.b]}};//local var 
models.a = { validate: [this.a, this.b]};//global