JavaScript模块模式和这个

我已经开始尝试Node,并且在一个文件中工作。 这是我的代码的基本原则:

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

这工作得很好。 现在我想将validationfunction移到它自己的文件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”。 我可以通过更改为this.a来解决这个问题,但是为什么在没有this关键字之前工作呢?

Validation (没有new关键字)不是一个构造函数,因此使用它来处理全局对象上下文。

试试这个:

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

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

除了你的实际问题。 你必须使用this.a因为没有本地作用域variables被导出,并且可以作为ab (尽pipe这是全局对象发生的)。 你当然可以withwith (this) models["a"] = {validate: [a, b]})但最好是使用它。 所以答案是你必须使用this.a

为什么没有这个工作呢? 简单,正如我在我的评论中所述:

简单地说,因为IIFE是在validation的环境中调用的,但是您使用的a告诉JS为一个名为avariables扫描范围(当前和最后,一直到全局)。
this.a告诉JS在上下文对象的原型链中查找名为a属性 ,即Validation

你可以写

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

validation将通过范围扫描被parsing为全局var validation 。 然后,通过this.a简单地访问a属性,就像现在一样。

注意:
在你的IIFE中写models["a"]并不相加: models就像你的代码所代表的那样是一个暗含的全局,这是邪恶的!
看起来, models是一个对象,但是,我不明白为什么你会设置一个属性使用括号符号,为什么不写:

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

你有两个重大的错误。

 module.exports.Validation = Validation(); 

调用函数Validation (没有新的),并将返回的对象导​​出为Validation

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

调用导出的Validation (不是函数),而是上面创build的对象。

最有可能的是,你想导出构造函数,然后用它来构造一个对象?

 module.exports = Validation; ... var Validation = require('./validation'); var obj = new Validation(); 
Interesting Posts