将继承与模块模式相结合

Posted

技术标签:

【中文标题】将继承与模块模式相结合【英文标题】:Combining inheritance with the module pattern 【发布时间】:2012-01-30 18:32:25 【问题描述】:

我喜欢返回构造函数的模块模式,如下所述: http://elegantcode.com/2011/02/15/basic-javascript-part-10-the-module-pattern/

但是我不确定如何从使用此模式实现的对象继承。假设我有一个这样实现的父对象......

namespace('MINE');  

MINE.parent = (function()  
    // private funcs and vars here

    // Public API - constructor
    var Parent = function (coords) 
       // ...do constructor stuff here
    ;

    // Public API - prototype
    Parent.prototype = 
       constructor: Parent,
       func1:  function ()     ... ,
       func2:  function ()     ... 
    

    return Parent;
 ());

如何定义一个子对象,它也使用从parent 继承的模块模式,以便我可以选择性地覆盖,例如func2

【问题讨论】:

请注意,您提供的代码有一个错误——您将构造函数设置为undefined。我已经编辑修复它。 我刚刚在这里***.com/questions/16659326/…问了一个类似的问题-想知道您对此有何看法。 【参考方案1】:
MINE.child = (function () 

  var Child = function (coords) 
    Parent.call(this, arguments);    
  

  Child.prototype = Object.create(Parent.prototype);

  Child.prototype.constructor = Child;
  Child.prototype.func2 = function ()  ... ;

  return Child;

());

【讨论】:

谢谢。这是一个非常简洁明了的答案,对我来说效果很好。我确实喜欢这种模式,因为它包含一次性初始化、封装以及上面的代码以及继承。您认为该模式有什么重大缺陷吗? @AndrewS。我个人讨厌命名空间。但这是一种风格偏好。您可以改用模块加载器。 这对我不起作用。如果我要实例化一个 MINE.child,我将无法访问 func1(在 MINE.parent 中定义)。我错过了什么吗?孩子的 func2 是否应该替换父母的 func2? 这种方法的问题是你可以有一个等价的静态变量,但不能有私有变量。我仍在寻找更好的方法。 @juminoz 我知道的做私有实例变量的唯一非骇人听闻的方法是在构造函数中定义它们,并在构造函数中定义所有依赖它们的方法,this.method = .不幸的是,我非常不喜欢这种做事方式,因为它为每个实例创建一个新的函数对象,而不是重用原型上的那个。出于这个原因,我倾向于避免使用私有实例变量。【参考方案2】:

我从这个博客 (http://metaduck.com/08-module-pattern-inheritance.html) 中找到了更清洁的解决方案。例如:

function Parent(name) 
    // Private variables here
    var myName;

    // Constructor
    myName = name;

    // Public interface
    return 
        func1: function () alert("Parent func1. Name: " + myName); ,
        func2: function () alert("Parent func2. Name: " + myName); 
    


function Child(name) 
    // Private variables here
    var myName,
        exportObj;

    // Constructor
    // Inherit
    exportObj = Parent(name + "'s father");

    // Override
    exportObj.func2 = function () 
        alert("Child func2. Name: " + name);
    

    // Export public interface
    return exportObj;

一个例子可以在这里运行:http://jsfiddle.net/wt4wcuLc/

【讨论】:

以上是关于将继承与模块模式相结合的主要内容,如果未能解决你的问题,请参考以下文章

Java面向对象特性

java三大特性封装继承多态

将两个对象与继承和聚合相关联是不好的编程习惯吗?

是否可以将友谊与继承结合起来访问私有数据成员

将 CSS 模块与 Bootstrap 相结合

将标识符模式与“as”模式相结合