我可以“延长”吗?闭包定义的“类”在 JavaScript 中?

发布于 2024-09-16 00:44:36 字数 768 浏览 11 评论 0原文

我有一个像这样定义的Javascript“类”:

var Welcomer = function(name) {
  var pName = name;
  var pMessage = function() {
    return "Hi, " + pName + "!";
  };

  return {
    sayHi: function() {
      alert(pMessage());
    }
  };
};

new Welcomer('Sue').sayHi();

有没有一种方法可以“子类”Welcome,以便我可以重新定义公共方法并有权访问私有方法和变量?以下内容将使我能够访问公共方法,但不能访问私有方法:

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

I have a Javascript "class" defined like so:

var Welcomer = function(name) {
  var pName = name;
  var pMessage = function() {
    return "Hi, " + pName + "!";
  };

  return {
    sayHi: function() {
      alert(pMessage());
    }
  };
};

new Welcomer('Sue').sayHi();

Is there a way to "subclass" Welcomer in such a way that I can redefine the public methods and have access to the private methods and variables? The following will give me access to the public methods, but not to the private ones:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

╄→承喏 2024-09-23 00:44:36

您的问题的简单答案是

您无法执行任何操作来访问这些 var 定义的内容,除非您的函数位于同一范围内,或者您以某种方式“公开”信息(通过返回它或将其设置为 <代码>此)。

如果您有权编辑原始函数,则可以以这样的方式重写内容:这些函数可以“传递”到扩展函数中,这可以更改对象的“受保护”范围。下面的代码应该可以很好地理解我的建议。

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

The simple answer to your question is No.

You can't do anything to gain access to those var defined things, unless your function is in the same scope, or you somehow 'make public' the information (by returning it, or setting it on this).

If you have access to edit the original function though, you could rewrite things in such a way that those functions could be "passed" into an extending function, which can alter the "protected" scope of the object. The following code should give a good idea of what I am proposing.

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();
べ映画 2024-09-23 00:44:36

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

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

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

进一步阅读:

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

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

That "class" pattern is not a "class" pattern, it's known as a Module Pattern. It returns an object that has no ties to the function that created it other then availability of it's private variables. The returned object is NOT an instance of the function that created it.

When you call 'new Class()' it does create an instance of that function, but it also returns another object. Any further operations is actually on the returned object and not the instance.

In order to use inheritance, you really need to use prototypical inheritance properly, I suggest you read:

Further reading:

Sorry to leave you with reading material, but it seems to me you are exploring possibilities. These articles will give a deeper insight on the matter.

Once you know more on the matter, you will most likely ignore private members alltogether and use the _ prefix and just make it a public member like everyone else ;) It's just easier and private members are pointless anyways.

永言不败 2024-09-23 00:44:36

如果您确实需要继承,那么一些库将提供极大的帮助。一种选择是 trait.js,它实际上可能成为 javascript 的标准部分无论如何。如果这不能满足你的需求,像 jQuery 和prototype 这样的库有继承的帮助器。

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

为了更直接地回答你的问题,不。如果您设计的“类”不依赖于私有函数,您将会更轻松。

If you really need inheritance, there are some libraries out there that will help immensely. One option is trait.js, which may actually become a standard part of javascript at some point anyway. If that doesnt float your boat, libraries like jQuery and prototype have helpers for inheritance.

If you want to go with a minimal/from-scratch approach, I strongly suggest you use the prototype model for everything. You will see a large performance increase over the pattern you have in your examples.

To more directly address your question, no. You will have an easier time if you design your 'classes' so private functions aren't relied upon.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文