【问题标题】:How to inherit static methods from base class in JavaScript?如何从 JavaScript 中的基类继承静态方法?
【发布时间】:2011-07-23 10:14:59
【问题描述】:

我正在尝试使用原型继承方式在 JavaScript 中实现一些基本的 OOP。但是,我找不到从基类继承静态成员(方法)的方法。

我们可以使用原型来模拟基本类模型:

SomeClass = function(){
    var private_members;

    this.public_method = function(){
        //some instance stuff..
    };
};

Class.static_method = function(){
    //some static stuff;
};

//Inheritance
SubClass = function(){ //sub-class definition };
SubClass.prototype = new Class();

但是,SubClass 不会从 Class 继承 static_method

【问题讨论】:

  • Mootools 是您问题的答案! :)

标签: javascript oop inheritance static


【解决方案1】:

在经典 (OO) 继承模式中,静态方法实际上不会被继承下来。因此,如果您有一个静态方法,为什么不在需要时调用:SuperClass.static_method(),JavaScript 不需要保留额外的引用或相同方法的副本。

您还可以阅读此JavaScript Override Patterns 以更好地了解如何在 JavaScript 中实现继承。

【讨论】:

    【解决方案2】:

    对于 ES5,您需要使用 Object.assign 将静态方法从 BaseClass 复制到 SubClass,但对于 ES6,它应该可以在不使用 Object.assign 的情况下工作

    ES5 示例

    var BaseClass = function(){
    
    }
    
    BaseClass.sayHi = function(){
       console.log("Hi!");
    }
    
    var SubClass = function(){
    
    }
    
    Object.assign(SubClass , BaseClass);
    
    BaseClass.sayHi();   //Hi
    SubClass.sayHi(); //Hi

    ES6 示例

    class BaseClass {
       static sayHi(){
         console.log("Hi!");
       }
    }
    
    class SubClass extends BaseClass{
    
    }
    
    BaseClass.sayHi()   //Hi
    SubClass.sayHi() //Hi

    【讨论】:

    • 当然,从技术上讲,Object.assign 也是 ES6,但您可以轻松地对其进行 polyfill 或将其替换为赋值循环。
    【解决方案3】:

    在您的示例代码之后,您可以这样做:

    for (var i in Class) {
        SomeClass[i] = Class[i];
    }
    

    将静态成员从Class 复制到SubClass

    如果您使用的是 jQuery,请查看来自 JavaScriptMVCjQuery.Class 插件。或者,您可以扩展 John Resig 的 Simple JavaScript Inheritance 以获得更多与库无关的系统。

    【讨论】:

    • 我更喜欢这个答案,因为它允许您为某些子类自定义静态方法,或者如果您想为每个/某些子类设置单独的静态属性。
    【解决方案4】:

    试试这个:

    class BaseClass {
        static baseMethod () {
            console.log("Hello from baseMethod");
        }
    }
    
    class MyClass extends BaseClass {
        constructor(props) {
            super(props);
        }
    }
    
    Object.assign(MyClass, BaseClass);
    

    他们的关键是Object.assign,它应该是每个人最好的新朋友。您现在可以使用MyClassBaseClass 调用任何基本方法,如下所示:

    MyClass.baseMethod();
    

    您可以在this pen 上看到这一点。

    享受吧!

    【讨论】:

    • 这个答案做我想要的,关键是使用“Object.assign()”的代码行
    • Object.setPrototypeOf(MyClass, BaseClass) 将避免破坏任何被覆盖的静态方法。
    • 这个答案很适合这个问题。虽然这是一个可行的解决方案,但在大多数浏览器支持 class 表达式之前几年就提出了这个问题,并且示例代码显然使用函数原型来实现继承。
    • 它在 ES6 中 works without the assignment
    • 正如@chocolateboy 提到的,这个答案是错误的。不需要Object.assign,您可以通过运行MyClass.baseMethod() 来验证这一点
    【解决方案5】:

    您是如何实现“静态”方法的?由于 JavaScript 没有原生类/实例对象模型,这完全取决于您如何设计自己的类系统。

    如果您希望能够继承任何东西,则必须使用SomeClass.prototype 对象,而不是将任何东西直接放在SomeClass 构造函数上。因此,本质上您将静态方法定义为普通实例方法,但不关心传递给它们的 this 的值。

    【讨论】:

      【解决方案6】:

      您可以通过this.constructor[staticField]访问static fields

      class A {
        static get Foo() { return 'Foo'; }
        
        constructor() {
          console.log(`Class ${this.constructor.name}`, this.constructor.Foo);
        }
      }
      
      class B extends A {
          static get Foo() { return 'Baz'; }
      }
      
      class C extends A {}
      
      const a = new A();
      const b = new B();
      const c = new C()

      【讨论】:

      • 直接附加到构造函数的函数不会被继承,除非您直接将它附加到 Object 原型,但是它对所有对象可见,而不仅仅是所需类的子级。
      猜你喜欢
      • 2022-10-06
      • 2012-06-21
      • 2011-02-13
      • 2010-10-05
      • 1970-01-01
      • 1970-01-01
      • 2011-06-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多