Javascript"抽象方法"

ora*_*nge 9 javascript oop jquery overloading object-literal

我的术语有点偏,所以请在必要时随意纠正.我想重载javascript和'基类'中的函数,以利用重载方法以及继承类来访问基类方法.到目前为止,我想出了一个(工作)混合jquery.extend()和对象文字,但这看起来并不漂亮.我想知道是否有更好的方法(可以使用jquery).

var Base = new function(args, m) {
   $.extend(this, m);
   var self = this;
   this.bar = function() {
     self.foo();
   }
   this.foo = function() {
     self.blah();
   }
   this.dosomething = function() {}
};

var Child = function(arg1) {
   $.extend(this, new Base(args, {
     blah: function() {
       self.dosomething()
     }
   }));
}
Run Code Online (Sandbox Code Playgroud)

Ben*_*aum 17

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

没有必要使用jQuery或其他库来实现这一目标.考虑使用语言的做事方式.

原型

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

在MDN上有关它的教程中有详细解释.

你的具体情况

如果我想要一个BaseChild类,其中Base有一个Child需要覆盖的方法,我们需要做的就是将它分配给该链中较低的位置.

查找的顺序是

Child Object --> Child's prototype (a Base object) --> Base's prototype (an Object)
Run Code Online (Sandbox Code Playgroud)

例如,假设您有一个类Base

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();
Run Code Online (Sandbox Code Playgroud)

我希望Child以不同的方式实现Bar,在这种情况下我可以做到

Child.prototype.bar = function(){
   console.log("World");
}
Run Code Online (Sandbox Code Playgroud)

结果如何

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
Run Code Online (Sandbox Code Playgroud)

注意JavaScript中的抽象类

抽象方法继承的两个主要原因是在基于经典继承(如Java)的语言中使用的是多态和代码共享.

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

至于多态性,JavaScript是一种带有鸭子类型的动态语言.这意味着它根据对象的能力而不是声明它们的方式来查看对象.如果有几个对象有一个名为my的方法,那么如果它们位于数组或其他集合中,则在每个对象上调用该方法bar没有问题.在Java中需要通用接口,类型或祖先.

由于这些原因,抽象类之类的东西在JavaScript中不起作用.


Bri*_*and 2

我建议按照CoffeeScript 的方式进行操作。您可以将第一个var声明放在单独的文件中,以使代码看起来美观。据我所知__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();
Run Code Online (Sandbox Code Playgroud)

或者,如果您可以使用 CoffeeScript,它看起来像这样:

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

class Apple extends Fruit
  constructor: ->
    console.log "New apple"
    super
Run Code Online (Sandbox Code Playgroud)