代码之家  ›  专栏  ›  技术社区  ›  James A. Rosen

我可以在Javascript中“扩展”闭包定义的“类”吗?

  •  15
  • James A. Rosen  · 技术社区  · 16 年前

    我有一个Javascript“类”定义如下:

    var Welcomer = function(name) {
      var pName = name;
      var pMessage = function() {
        return "Hi, " + pName + "!";
      };
    
      return {
        sayHi: function() {
          alert(pMessage());
        }
      };
    };
    
    new Welcomer('Sue').sayHi();
    

    有没有办法“子类化” Welcomer 这样我就可以重新定义公共方法并访问私有方法和变量了?以下内容将允许我访问公共方法,但不能访问私有方法:

    var UnhappyWelcomer = function(name) {
      var pSadMessage = function() {
        // won't work, b/c I don't have access to pMessage
        return pMessage() + " Miserable day, innit?";
      };
    
      return {
        sayHi: function() {
          alert(pSadMessage());
        }
      };
    };
    UnhappyWelcomer.prototype = Welcomer(); // failed attempt at inheritance
    
    new UnhappyWelcomer().sayHi();
    
    3 回复  |  直到 16 年前
        1
  •  10
  •   gnarf    16 年前

    不 .

    你不能做任何事来获取这些信息 var 定义的东西,除非你的函数在同一个范围内,或者你以某种方式“公开”了信息(通过返回它,或者设置它) this

    var Welcomer = function(name) {
      var _protected = {
        name: name,
        message: function() {
          return "Hi, " + _protected.name + "!";
        }
      };
    
      return {
        extendWith: function(extender) {
          extender.call(this, _protected);
          return this;
        },
        sayHi: function() {
          alert(_protected.message());
        }
      };
    };
    
    var UnhappyWelcomer = function(name) {
      var self = Welcomer(name).extendWith(function(_protected) {
        _protected.sadMessage = function() {
           return _protected.message() + " Miserable day, innit?";
        };
        // extending the public while still having scope to _protected...
        this.sayHi = function() {
          alert(_protected.sadMessage());
        };
      });
      return self;
    };
    
    UnhappyWelcomer('bob').sayHi();
    
        2
  •  8
  •   BGerrissen    16 年前

    Module Pattern . 它返回一个对象,该对象与创建它的函数没有任何关系,除非它的私有变量可用。返回的对象不是创建它的函数的实例。

    当您调用'new Class()'时,它确实会创建该函数的一个实例,但它也会返回另一个对象。任何进一步的操作实际上都在返回的对象上,而不是在实例上。

    为了使用继承,您确实需要正确地使用原型继承,我建议您阅读:

    很抱歉给你留下阅读材料,但在我看来你在探索各种可能性。这些文章将对这件事有更深刻的见解。

    一旦你知道了更多关于这个问题的信息,你很可能会忽略所有的私有成员,而使用uux前缀,让它像其他人一样成为一个公共成员;)这很简单,而且私有成员无论如何都是毫无意义的。

        3
  •  1
  •   jdc0589    16 年前

    如果您真的需要继承,那么有一些库将非常有用。一个选择是 trait.js ,这在某种程度上可能会成为javascript的标准部分。如果这不能让您轻松上船,那么像jQuery和prototype这样的库就有了继承的助手。

    如果您想使用最小/从头开始的方法,我强烈建议您对所有内容都使用原型模型。与示例中的模式相比,您将看到性能有很大的提高。