通过调用祖先函数来inheritanceJavaScript

我正在试验(对我来说)一种新型的inheritance。 我想通过一个参数来调用inheritance的函数,这个参数决定了哪个inheritance对象被返回。

下面是一个例子来说明我的意思:

function Localizor(type) { this.language = "English" this.endonym = "English" if (window[type]) { return new window[type]() } } Localizor.prototype.native = function native() { return "I speak " + this.endonym } Localizor.prototype.english = function () { return "I speak " + this.language } function French () { this.language = "French"; this.endonym = "français" } French.prototype = new Localizor() French.prototype.native = function french() { return "Je parle " + this.endonym } function Thai () { this.language = "Thai"; this.endonym = "ไทย" } Thai.prototype = new Localizor() Thai.prototype.native = function thai() { return "พูดภาษา" + this.endonym } 

如果我没有参数(或无效的参数)调用new Localizor() ,我得到一个简单的英文对象。 如果我用“法语”或“泰语”的说法调用它,我会得到一个inheritance者覆盖一些inheritance的方法的对象,以便它说法语或泰语。 例如:

 var thai = new Localizor("Thai") var feedback = thai.language + " | " + thai.endonym + " | " + thai.english() + " | " + thai.native() console.log(feedback) 

这给了我Thai | ไทย | I speak Thai | พูดภาษาไทย的输出 Thai | ไทย | I speak Thai | พูดภาษาไทย Thai | ไทย | I speak Thai | พูดภาษาไทย

我有三个问题:
1.这种types的inheritance是否已经logging在某个地方(是否有名字)?
2.这样做有什么危险吗?
3.这个例子检查window[type]是否存在,这在浏览器中工作是很好的。 如果这是在node.js模块中,是否有一个确定模块内是否存在函数的等效方法?

编辑为响应Zero21xxx

我发现了一个检测模块中是否存在构造函数的方法,但是对于我来说,这看起来危险很多。 它有什么风险? 有什么更好的方法可用?

 function extend(Child, Parent) { function F() {} F.prototype = Parent.prototype Child.prototype = new F() //Child.prototype.constructor = Child Child.parent = Parent.prototype } function Localizor(type) { this.language = "English" this.endonym = "English" this.French = function français () { this.language = "French"; this.endonym = "français" } extend(this.French, this) this.French.prototype.native = function french() { return "Je parle " + this.endonym } this.Thai = function ไทย () { this.language = "Thai"; this.endonym = "ไทย" } extend(this.Thai, this) this.Thai.prototype.native = function thai() { return "พูดภาษา" + this.endonym } if (typeof this[type] === "function") { return new this[type]() } } Localizor.prototype.native = function native() { return "I speak " + this.endonym } Localizor.prototype.english = function () { return "I speak " + this.language } module.exports = Localizor 

在我看来,你应该有三个单独的构造函数,用于EnglishFrenchThai ,它们从一个共同的构造函数(我们称之为Locale )inheritance而来。 它看起来如下:

 function Locale(constructor, language, endonym, native) { this.constructor = constructor; this.language = language; this.endonym = endonym; this.native = function () { return native + this.endonym; }; } Locale.prototype.english = function () { return "I speak " + this.language; }; function English() {} function French() {} function Thai() {} English.prototype = new Locale(English, "English", "English", "I speak "); French.prototype = new Locale(French, "French", "français", "Je parle "); Thai.prototype = new Locale(Thai, "Thai", "ไทย", "พูดภาษา"); 

这导致关注的分离 :每个构造函数都只是按照它的意图进行操作。 没有什么比这更less的了。 现在您可以创build一个localizer函数,如下所示:

 function localizer(language) { switch (language) { case "French": return new French; case "Thai": return new Thai; default: return new English; } } 

因此,所有你需要做的是调用localizer获得所需的Locale

  1. 是的,这是人们经常试图取得不同程度成功的“伪古典”遗产。 看看这个
  2. 那么你现在的方式有点难以阅读。 你写的代码说创build一个Localizor对象,但是你传回一个Thai对象。 这可能很难追查错误。
  3. 是的,有办法检查这样的事情,这取决于你如何构build模块。

我的build议是稍微重写一下

 function Localizor(language, endonym) { this.language = language; this.endonym = endonym; } Localizor.prototype.native = function native() { return "I speak " + this.endonym; }; Localizor.prototype.english = function () { return "I speak " + this.language; }; function French (language, endonym) { Localizor.apply(this, arguments); } French.prototype = new Localizor(); French.prototype.native = function french() { return "Je parle " + this.endonym; }; function Thai (language, endonym) { Localizor.apply(this, arguments); } Thai.prototype = new Localizor(); Thai.prototype.native = function thai() { return "พูดภาษา" + this.endonym; }; 

这样,你可以调用正确的构造函数并获取相应的对象。 您还可以调用“基类”构造函数,并附加language和自变名属性,而无需复制和粘贴该代码。 你也不需要检查你正在做的types,因为你正在声明它们是如何工作的。 最后,如果你想,你可以让你的Localizor函数接受第三个参数,这将是string“我说”或什么,然后你不会事件需要多个对象。

这里是一个可以惹恼的游乐场。

服务器或客户端,我认为这是一个更好的方法。