首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过调用祖先函数进行JavaScript继承

通过调用祖先函数进行JavaScript继承
EN

Stack Overflow用户
提问于 2013-09-01 12:11:44
回答 2查看 333关注 0票数 2

我正在试验一种新的继承方式。我想用一个参数来调用继承的函数,该参数决定返回哪个继承对象。

这里有一个例子来说明我的意思:

代码语言:javascript
复制
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(),就会得到一个简单的英语对象。如果我用“法语”或“泰语”的参数来调用它,就会得到一个对象,在这个对象中,继承者会覆盖一些继承的方法,这样它就会说法语或泰语。例如:

代码语言:javascript
复制
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进行编辑

这是我发现的一种检测模块中存在构造函数的方法,但在我看来,这是危险的乱流。它有什么风险?有什么更好的办法吗?

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-09-01 15:22:33

在我看来,您应该为EnglishFrenchThai拥有三个独立的构造函数,它们继承于一个公共构造函数(让我们称之为Locale)。其内容如下:

代码语言:javascript
复制
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函数,如下所示:

代码语言:javascript
复制
function localizer(language) {
    switch (language) {
    case "French": return new French;
    case "Thai": return new Thai;
    default: return new English;
    }
}

因此,您需要做的就是调用localizer以获得所需的Locale

票数 3
EN

Stack Overflow用户

发布于 2013-09-01 13:30:11

  1. 是的,这是一种“伪古典”式的继承,人们常常试图通过不同程度的成功来实现这种继承。查看
  2. 好吧,你现在的方式有点难读。您编写的代码说创建一个Localizor对象,但是您将返回一个Thai对象。很难追踪到错误。
  3. 是的,有检查这类事情的方法,这取决于您如何构造模块。

我的建议是像这样稍微重写一下

代码语言:javascript
复制
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;
};

这样,您就可以调用正确的构造函数并获得相应的对象。您还可以调用“基类”构造函数并附加languageendonym属性,而不必复制和粘贴该代码。您也不需要像当前这样检查类型,因为您正在声明它们是如何工作的。最后,如果您需要,可以让您的Localizor函数接受第三个参数,即字符串"I take“或其他什么,这样您就不会需要多个对象了。

这里是一个你可以捣乱的操场。

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18558324

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档