你如何在Javascript中提取依赖于局部变量的常用方法?

时间:2012-09-24 17:14:54

标签: javascript node.js refactoring

我正在使用Node.js并为我的不同对象创建一些模型。这是他们目前看起来的简化版本。

var Foo = module.exports = function () {

    var values = { type: 'foo', prop1: '', prop2: '' };

    function model() {}

    model.init = function(val) {
        _.extend(values, val);
        return model;
    }

    model.store = function(cb) {
        db.insert(values.type, values, cb);
    }

    model.prop1 = function(val) {
        if(!arguments.length) return values.prop1;
        values.prop1 = val;
        return model;
    }

    return model;
}

然后我可以做:

var foo = Foo();
foo.init({prop1: 'a', prop2: 'b'}).store(function(err) { ... }); 

许多函数,如model.initmodel.store对于每个模型都是相同的,但它们依赖于闭包中的局部变量,如values

有没有办法将这些函数拉入基类,然后我可以扩展每个模型而不是复制所有这些代码?我想最终得到类似的内容,但我不确定base类应该是什么样的,或者使用它来扩展Foo的正确方法。

var Foo = module.exports = function () {

    var values = { type: 'foo', prop1: '', prop2: '' };

    function model() { this.extend(base); }

    model.prop1 = function(val) {
        if(!arguments.length) return values.prop1;
        values.prop1 = val;
        return model;
    }

    return model;
}

1 个答案:

答案 0 :(得分:1)

是的,你可以做这样的事情;

model.js

/** require your db and underscore varialbles etc.. **/

module.exports = function(values, base) {
    var model = typeof base == 'function' ? base : function() {};

    model.init = function(val) {
        _.extend(values, val);
        return model;
    }

    model.store = function(cb) {
       db.insert(values.type, values, cb);
    }

    return model;
}

然后用法类似于;

var Foo = module.exports = function () {

    var values = { type: 'foo', prop1: '', prop2: '' };

    var model = require('/path/to/model.js')(values);

    model.prop1 = function(val) {
        if(!arguments.length) return values.prop1;
        values.prop1 = val;
        return model;
    }

    return model;
}

如果需要扩展构造函数

var Foo = module.exports = function () {

    var values = { type: 'foo', prop1: '', prop2: '' },
        model  = function() { ...something here... };

    require('/path/to/model.js')(values, model);

    model.prop1 = function(val) {
        if(!arguments.length) return values.prop1;
        values.prop1 = val;
        return model;
    }

    return model;
}