Javascript";“抽象方法”;

Javascript";“抽象方法”;,javascript,jquery,oop,overloading,object-literal,Javascript,Jquery,Oop,Overloading,Object Literal,我的术语有点不合适,所以在必要的地方请随意更正。我想在javascript和“基类”中重载一个函数,以利用重载方法和继承的类来访问基类方法。到目前为止,我提出了jquery.extend()和对象文本的(有效)组合,但这看起来并不漂亮。我想知道是否有更好的方法(可以使用jquery) 我建议你用这种方式做。您可以将第一个var声明放在一个单独的文件中,以保持代码外观良好。据我所知,\u extends相当于$。extends var __hasProp = {}.hasOwnProperty,

我的术语有点不合适,所以在必要的地方请随意更正。我想在javascript和“基类”中重载一个函数,以利用重载方法和继承的类来访问基类方法。到目前为止,我提出了
jquery.extend()
和对象文本的(有效)组合,但这看起来并不漂亮。我想知道是否有更好的方法(可以使用jquery)


我建议你用这种方式做。您可以将第一个
var
声明放在一个单独的文件中,以保持代码外观良好。据我所知,
\u extends
相当于
$。extends

var __hasProp = {}.hasOwnProperty,
  __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };


var Fruit = (function() {

  function Fruit() {
    console.log("New fruit");
  }

  return Fruit;

})();

var Apple = (function(_super) {

  __extends(Apple, _super);

  function Apple() {
    console.log("New apple");
    Apple.__super__.constructor.apply(this, arguments);
  }

  return Apple;

})(Fruit);

var apple = new Apple();
或者,如果您可以使用CoffeeScript,它看起来是这样的:

class Fruit
  constructor: ->
    console.log "New fruit"

class Apple extends Fruit
  constructor: ->
    console.log "New apple"
    super

您正在寻找的是一种跨对象共享功能的方法。 这正是JavaScript原型继承模型擅长的事情

不需要使用jQuery或其他库来实现这一点。考虑用语言的方式做事。

原型 在JavaScript中,对象具有“原型”。当JavaScript在没有方法的对象中查找方法时,它会在原型“链”上查找该方法。因此,您所需要做的就是在该链的较低级别覆盖该功能

这将在中详细解释

你的具体情况 如果我想要一个
Base
Child
类,其中
Base
有一个
Child
需要重写的方法,那么我们所需要做的就是将它分配到该链中较低的任何位置

查找的顺序是

Child Object --> Child's prototype (a Base object) --> Base's prototype (an Object)
例如,假设您有一个类基

function Base(){

}
Base.prototype.bar = function() {
     //bar logic here
     console.log("Hello");
};
Base.prototype.foo= function() {
     //foo logic here
};

Function Child(){

}

Child.prototype = new Base();
我希望Child以不同的方式实现Bar,在这种情况下我可以这样做

Child.prototype.bar = function(){
   console.log("World");
}
导致

var a = new Base();
a.bar(); //outputs "Hello" to the console
var b = new Child();
b.bar(); //outputs "World" to the console
         //The Base instance that is the prototype of b has the bar method changed above
关于JavaScript中抽象类的说明 在基于经典继承(如Java)的语言中使用抽象方法继承的两个主要原因是多态性和代码共享

在JavaScript中,两者都不是问题。使用原型继承也可以轻松地完成代码共享。此外,您可以使用任何函数并在另一个上下文中运行它。例如,我甚至可以通过执行
b.bar.call([])
调用空数组上
子对象的
bar
方法

至于多态性,JavaScript是一种带有duck类型的动态语言。这意味着它基于对象的能力而不是它们的声明方式来查看对象。如果几个对象都有一个名为
bar
的方法,如果它们在数组或其他集合中,我会对每个对象调用该方法。在Java中,需要一个公共接口、类型或祖先


由于这些原因,抽象类之类的东西在JavaScript中并没有起到很大的作用。

我想这是@Alexander,来自该页面:“我写JavaScript已经8年了,我从来没有发现需要使用uber函数。超级概念在经典模式中相当重要,但在原型模式和功能模式中似乎没有必要。我现在认为我早期支持JavaScript经典模型的尝试是一个错误。”@BenjaminGruenbaum-我认为你和Alexander都同意Crockford的观点,即经典继承不适合JavaScript,不是吗?@JaredFarrish,我想我们(同意),我不是在争论,我想把Crockford的结论从这一页带到这里会很好,这样它会更清晰。这可能是那一页最重要的部分:)@BenjaminGruenbaum-是的,你会想到他会把那一点放在顶部。Wrrrd。如果有几个对象有一个叫做bar的方法,我会毫不犹豫地调用这个方法如果它们在数组或其他集合中,我想我会遵循这个注释,但是你能代码化吗?jsFiddle在加载方面很挑剔,所以我还没有看到你提供的内容,但我也希望看到你提到的经典意义上的备选方案(公共接口、类型或anscestor)。当然,你不必这么做,但这似乎很明显,特别是对于那些经典知识中“负担沉重”的人。我还添加了一个jsbin(如果JSFIDLE不适合你)。对于同一个例子,在Java上,你需要一个
Barrable
接口,使用一个方法
bar
,每个对象都需要显式类(
Animal
Car
Kid
相应地,每个类都在自己的
.java
文件中),这些类在其类定义中都需要一个
实现Barrable
。或者,您可以确定一个孩子、一辆车和一个动物都有一个祖先,但这可能不太可能:)听起来像PHP(除了PHP将
Abstract
Interface
定义分为带方法和不带方法)。我不能说经典继承本身有任何问题,但我喜欢Javascript的原型直接性。如果Base需要构造一个参数,这将如何工作?所有这些
.prototype.foo=新函数都可以吗(){}东西进入
函数Child(){}还是必须在外部赋值?
var a = new Base();
a.bar(); //outputs "Hello" to the console
var b = new Child();
b.bar(); //outputs "World" to the console
         //The Base instance that is the prototype of b has the bar method changed above