我可以在JavaScript中“扩展”闭合定义的“类”?
-
01-10-2019 - |
题
我有一个像这样定义的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()”时,它确实会创建该函数的实例,但也返回另一个对象。实际上,任何其他操作实际上都在返回的对象上,而不是实例上。
为了使用继承,您确实需要正确使用原型继承,我建议您阅读:
- 原型继承 道格拉斯·克罗克福德(Douglas Crockford)
- JavaScript中的私人成员 道格拉斯·克罗克福德(Douglas Crockford)
- JavaScript中的原型和继承 斯科特·艾伦(Scott Allen)(注意: 原始 不是标准)
进一步阅读:
很抱歉让您阅读材料,但在我看来,您正在探索可能性。这些文章将对此事有更深入的了解。
一旦您对此事有了更多了解,您很可能会忽略私人成员,并使用_前缀,并像其他所有人一样使其成为公共成员;)这很容易,而且私人成员无论如何都毫无意义。
如果您确实需要继承,那么那里有一些库会极大地帮助您。一个选择是 特质, ,无论如何,这实际上可能成为JavaScript的标准部分。如果那没有浮动您的船,那么诸如jQuery和原型的图书馆都有继承的帮助者。
如果您想采用最小/从划痕的方法进行,我强烈建议您将原型模型用于所有内容。您会看到与示例中的模式相比,您的性能大大提高。
更直接地解决您的问题,否。如果设计“课”,您将有更轻松的时间,因此不依赖私人功能。