模块模式和继承

时间:2013-11-17 18:24:30

标签: javascript

我想问一下下面的代码是否是使用模块模式实现继承的一种方法。我很感激任何建议。

var Parent = (function() {

    function construct(x, y) {
        this.x = x || 0;
        this.y = y || 0;
    };

    return construct;
})();

var Child = (function() {

    function construct() {

    };

    construct.prototype = new Parent();

    return construct;
})();

2 个答案:

答案 0 :(得分:0)

'模块模式'和继承是正交的。只要您在定义Child时能够获得对Parent的引用,任何进行继承的技术都应该可以正常工作。

有许多方法可以进行继承。我倾向于建议使用内置于你必须使用的任何库中的任何内容,但是如果你想手动完成,那么你将原型设置为父实例的新功能是相当糟糕的。一个简单而好的表述就是这样的(es5):

function Child() {
    Parent.call(this);
}
Child.prototype = Object.create(Parent.prototype, {
    constructor: {value:Child, writable: true,enumerable: false,configurable: true}
});

关于模块模式,我建议选择AMD格式并使用RequireJS之类的工具来帮助您定义模块,或者可能使用CommonJS的Node.js风格并使用browserify为浏览器构建它。定义模块包装器中的每个类比不这样做更好(主要是因为它允许你创建私有类级别变量),但是并没有真正获得模块的一些大好处 - 使用require机制导入其他模块是比从全局变量中获取它们更好,而不是将它们定义为全局变量将阻止你过多地破坏全局范围并且可以避免令人讨厌的冲突。

如果要继续手动进行包装,请考虑使用类的名称命名构造函数,而不是“构造”,因为它对调试非常有帮助。

答案 1 :(得分:0)

将构造函数和原型放在IIFE中会导致一些开销,因为您为每个函数创建了闭包,但是您只为对象定义而不是为每个创建的对象创建闭包。

我更喜欢不将Object定义放在IIFE中,因为我从不使用privates并在函数减速后直接设置继承:Child.prototype=Object.create(Parent.prototype);。有关原型和构造函数here的更多信息。

以下代码演示了具有私有共享成员的IIFE,例如特定的私有成员检查以前发布的链接。

var Parent = (function() {
    var sharedPrivateVal = 22;
    var privateFn = function(me){
      console.log("Current instance is:",me);
      return("returned from 'private' method");
    }
    function construct(x, y) {
        this.x = x || 0;
        this.y = y || 0;
    };
    //all functions here are privileged even though they never need
    //access to 'private' variables
    construct.prototype.someFn=function(){
      console.log("someFn in parent");
    };
    construct.prototype.privilegedFn=function(){
      console.log("Accessing shared 'private' varaible:",sharedPrivateVal);
    };
    construct.prototype.privilegedFn2=function(){
      console.log(privateFn(this));
    };
    return construct;
}());

var Child = (function(p) {
    var _super = p.prototype;
    function construct() {
      p.apply(arguments);//re use parent constructor code
    };

    construct.prototype = Object.create(_super);//polyfill Object.create for older browsers
    construct.prototype.someFn=function(){
      _super.someFn.apply(arguments);//calling parent functon
      console.log("someFn in child");
    };
    construct.prototype.privilegedFn2=function(){
      console.log("No access to 'privates' when overriding"
        ,typeof privateFn);//you could re declare the function here 
                           //but you'll be doing copy and paste inheritance
                           //maybe consider widening IIFE scope and have
                           //both Parent and Child in an one IIFE if you must
                           //use private methods
      _super.privilegedFn2.apply(this,arguments);//ok when calling parent
    };


    return construct;
}(Parent));

var c = new Child();
c.someFn()
c.privilegedFn();
c.privilegedFn2();