JavaScript模块模式和此
我已经开始试验Node,并且在单个文件中工作。 这是我的代码的基本原则:JavaScript模块模式和此,javascript,node.js,module-pattern,Javascript,Node.js,Module Pattern,我已经开始试验Node,并且在单个文件中工作。 这是我的代码的基本原则: function Validation(){ this.a = function(){...} this.b = function(){...} return this; } var validation = Validation(); (function(){ models["a"] = { validate: [a, b] } }).call(validati
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未定义”。
我可以通过将a
更改为this.a
来解决这个问题,但是为什么它以前在没有this
关键字的情况下工作?验证(没有new
关键字)不是构造函数,所以在它内部使用this
可以处理全局对象上下文
请尝试以下方法:
function Validation() {
return {
a: function() {...},
b: function() {...}
};
}
或者使用module.exports.Validation=new Validation()
除了你的实际问题。您必须使用this.a
,因为没有导出局部作用域变量,并且可以作为a
和b
使用(尽管它发生在全局对象上)。当然,您可以将与
一起使用(与(this)models[“a”]={validate:[a,b]})
但是最好使用它。所以答案是你必须使用这个。你有两个主要错误
module.exports.Validation = Validation();
调用函数Validation
(没有新的this
),并将返回的对象导出为Validation
var validation = require('./validation').Validation();
调用导出的验证
,该验证不是函数,而是您在上面创建的对象
很可能,您想导出构造函数,然后使用它来构造对象
module.exports = Validation;
...
var Validation = require('./validation');
var obj = new Validation();
为什么没有这个它就不能工作?很简单,正如我在评论中所说:
这仅仅是因为IIFE是在验证的上下文中调用的
,但是使用a
会告诉JS扫描范围(当前的和向上的,一直到全局的),以查找名为a
的变量
this.a
告诉JS在上下文对象的原型链中查找名为a
的属性,即Validation
var validation = require('./validation').Validation();
你本来可以写的
(function()
{
models["a"] = {
validate: [a, b]
};
}());
验证
将通过范围扫描解析为全局var验证
。然后,您只需通过this.a
访问a
属性,就像现在一样
注:
在你的生活中写模型[“a”]
是没有意义的:模型
就你的代码而言,是一个隐含的全局,这是邪恶的
不过,models
似乎是一个对象,但我不明白为什么要使用括号符号设置属性,为什么不写:
var models = {a: { validate: [this.a, this.b]}};//local var
models.a = { validate: [this.a, this.b]};//global
对不起,我实际上是在做你说的第二件事。在我的简化示例中只是一个输入错误。您尝试了第一种方法吗?是的,但它给出了完全相同的结果。@dfsq:您没有回答实际的问题:为什么a
需要这一点。a
。仅仅是因为iLife是在验证的上下文中调用的,并且a
告诉JS扫描范围(当前和向上,一直到全局)用于名为a
的变量。a
告诉JS在上下文对象的原型链中查找名为a
的属性,即Validation
。您可以编写(function(){Validation.a}());
验证
将被解析为全局var验证
,我正在访问它的a
属性如果你只构建了一次验证对象,为什么你要使用一个构建的对象?你没有解决实际问题:为什么OP需要这个。a
而不是a
这个属性实际问题是对模块工作方式的明显误解。了解此
的详细信息是没有用的,因为它仍然是错误的。