JavaScript模块模式和这个

时间:2014-02-25 13:17:29

标签: 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(validation);

这完全没问题。现在我想将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”。 我可以通过将a更改为this.a来解决此问题,但为什么在没有this关键字的情况下才能解决此问题?

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

为什么没有this它没有用?简单,正如我在评论中所述:

仅仅因为在validation的上下文中调用了IIFE,但是你使用a告诉JS扫描范围(当前和上升,一直到全局)变量名为a this.a告诉JS在上下文对象的原型链中查找名为a属性,即Validation

你可以写

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

validation将通过范围扫描解析为全局var validation。然后,您只需访问a属性,就像现在一样,通过this.a

注意:
在你的IIFE中写models["a"]并没有加起来:models就像你的代码所代表的那样,是隐含的全球,这是邪恶的! 看来models似乎是一个对象,但是我不明白为什么要使用括号表示法设置属性,为什么不写:

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

答案 2 :(得分:0)

您有两个主要错误。

module.exports.Validation = Validation();

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

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

调用导出的Validation,它不是函数,而是您在上面创建的对象。

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

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