通过调用祖先函数继承JavaScript
JavaScript inheritance through a call to the ancestor function
我正在试验一种新的继承类型。我想用一个参数来调用继承的函数,该参数决定返回哪个继承对象。
这里有一个例子来说明我的意思:
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()
时没有参数(或参数无效),则会得到一个纯英文对象。如果我用"French"或"Thai"的自变量来调用它,我会得到一个对象,在该对象中,继承者覆盖了一些继承的方法,这样它就会说法语或泰语。例如:
var thai = new Localizor("Thai")
var feedback = thai.language + " | " + thai.endonym + " | " + thai.english() + " | " + thai.native()
console.log(feedback)
这给了我输出Thai | ไทย | I speak Thai | พูดภาษาไทย
。
我有三个问题:
1.这种类型的继承是否已经在某个地方记录在案(它有名字吗)
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
在我看来,English
、French
和Thai
应该有三个独立的构造函数,它们继承自一个公共构造函数(我们称之为Locale
)。它看起来如下:
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", "ไทย", "พูดภาษา");
这导致了关注点的分离:每个构造函数只做它想要做的事情。没有更多,没有更少。现在您可以创建一个localizer
函数,如下所示:
function localizer(language) {
switch (language) {
case "French": return new French;
case "Thai": return new Thai;
default: return new English;
}
}
因此,您所需要做的就是调用localizer
来获得所需的Locale
。
- 是的,这是一种"伪古典"的继承,人们经常试图获得不同程度的成功。看看这个
- 你现在的阅读方式有点难。您编写的代码说创建一个
Localizor
对象,但您会返回一个Thai
对象。这可能很难追踪错误 - 是的,有一些方法可以检查这些东西,这实际上取决于你如何构建模块
我的建议是稍微像这个一样重写这个
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
和endonym
属性,而无需复制和粘贴该代码。您也不需要像当前所做的那样检查类型,因为您正在声明它们的工作方式。最后,如果你愿意,你可以让Localizor
函数接受第三个参数,那就是字符串"I Speak"或其他什么,这样你就不需要多个对象了。
这是一个你可以乱搞的操场。
无论是服务器端还是客户端,我认为这是一个更好的方法。
- 以jquery方式继承Javascript
- JavaScript对象不是从原型链继承的
- 数据与Javascript中的继承冲突
- JavaScript对象继承问题
- Javascript嵌套函数属性继承
- 从类构造函数继承javascript
- Loaded()内容赢得't继承javascript
- 原型继承JavaScript在不同函数中使用变量
- 通过调用祖先函数继承JavaScript
- 如何从核心OpenERP 6.1继承javascript
- 安全地继承JavaScript中的原型
- 对经典和原型继承Javascript的混淆
- 不同文件中构造函数之间的部分继承(JavaScript)
- TypeScript:如何继承javascript构造函数
- 在c++中继承JavaScript函数
- 我如何继承javascript函数
- 通过__proto__原型来继承JavaScript是否不好
- 原型继承-Javascript原型:替换与添加
- 原型继承 - JavaScript 公开原型属性
- 多重继承 - JavaScript hasOwnProperty