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被导出,并且可以作为a
和b
(尽pipe这是全局对象发生的)。 你当然可以with
( with (this) models["a"] = {validate: [a, b]})
但最好是使用它。 所以答案是你必须使用this.a
为什么没有这个工作呢? 简单,正如我在我的评论中所述:
简单地说,因为IIFE是在validation
的环境中调用的,但是您使用的a
告诉JS为一个名为a
的variables扫描范围(当前和最后,一直到全局)。
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();