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();
4

3 回答 3

10

您的问题的 简单答案是否

你不能做任何事情来访问那些var定义的东西,除非你的函数在同一个范围内,或者你以某种方式“公开”信息(通过返回它,或者将它设置为 on 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();
于 2010-08-24T21:39:41.953 回答
8

该“类”模式不是“类”模式,它被称为模块模式。它返回一个对象,该对象与创建它的函数没有任何关系,除了它的私有变量的可用性。返回的对象不是创建它的函数的实例。

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

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

进一步阅读:

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

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

于 2010-08-24T21:56:26.050 回答
1

如果您真的需要继承,那么有一些库可以提供极大的帮助。一种选择是trait.js,它实际上可能在某个时候成为 javascript 的标准部分。如果这不能让你浮出水面,像 jQuery 和原型这样的库有继承的助手。

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

为了更直接地解决您的问题,不。如果您设计“类”,那么您将拥有更轻松的时间,因此不依赖私有函数。

于 2010-08-24T21:38:44.950 回答