我有一个像这样定义的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();
有帮助吗?

解决方案

您问题的简单答案是 .

您不能做任何事情来访问这些 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();

其他提示

“类”模式不是“类”模式,它被称为 模块模式. 。它返回一个与创建它的函数无关的对象,而不是其私有变量的可用性。返回的对象不是创建它的函数的实例。

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

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

进一步阅读:

很抱歉让您阅读材料,但在我看来,您正在探索可能性。这些文章将对此事有更深入的了解。

一旦您对此事有了更多了解,您很可能会忽略私人成员,并使用_前缀,并像其他所有人一样使其成为公共成员;)这很容易,而且私人成员无论如何都毫无意义。

如果您确实需要继承,那么那里有一些库会极大地帮助您。一个选择是 特质, ,无论如何,这实际上可能成为JavaScript的标准部分。如果那没有浮动您的船,那么诸如jQuery和原型的图书馆都有继承的帮助者。

如果您想采用最小/从划痕的方法进行,我强烈建议您将原型模型用于所有内容。您会看到与示例中的模式相比,您的性能大大提高。

更直接地解决您的问题,否。如果设计“课”,您将有更轻松的时间,因此不依赖私人功能。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top