【问题标题】:Workaround to static member inheritance静态成员继承的解决方法
【发布时间】:2013-04-17 19:05:36
【问题描述】:

我实际上正在从事一个项目,在该项目中我需要一堆对象(如果您愿意,可以使用类,而不是实例)来实现相同的行为。基本上,每个“类”都需要提供一种方法来操作包含它的每个实例的数组。

这样的编码让我很困扰:

function A() { ... }
A.instances = [];
A.someStaticMethod = function () {
    for (var i = 0 ; i < A.instances ; i++) {
        A.instances[i].doSomething();
    }
}
A.prototype.doSomething = function () { ... }

function B() { ... }
B.instances = [];
B.someStaticMethod = function () {
    for (var i = 0 ; i < B.instances ; i++) {
        B.instances[i].doSomething();
    }
}
B.prototype.doSomething = function () { ... }

我只是不喜欢复制/粘贴的代码。来自类语言,我自然认为我所要做的就是创建第三个类,该类将实现那些静态成员/方法并让我的其他类继承它。 我几乎不知道,你不能继承静态成员。

我愿意学习 javascript 是如何工作的,所以我想知道是否有任何方法可以在不必每次都复制代码的情况下获得想要的行为。

【问题讨论】:

  • 静态方法在其他语言中是如何继承的?
  • 他们不是,我猜。但是,我的问题仍然与静态属性有关。

标签: javascript inheritance static


【解决方案1】:

你可以尝试使用一个函数来增强你的对象,使用一种 mixin 函数。

function enhanceStatic(type) {
    type.instances = [];
    type.someStaticMethod = function () {
        for (var i = 0; i < type.instances.length; i++) {
            type.instances[i].doSomething();
        }
    };
}

function A(msg) {
    this.msg = msg;
}
enhanceStatic(A);
A.prototype.doSomething = function () {
    console.log("A: " + +this.msg);
}

function B(msg) {
    this.msg = msg;
}
enhanceStatic(B);
B.prototype.doSomething = function () {
    console.log("B: " + +this.msg);
}

A.instances = [new A(1), new A(2)];
B.instances = [new B(1), new B(2), new B(3)];
A.someStaticMethod();
B.someStaticMethod();

输出:

A: 1
A: 2
B: 1
B: 2
B: 3 

【讨论】:

  • 是的,这正是我所需要的。谢谢!
【解决方案2】:

有多种方法可以在 javascript 中实现类行为。值得一提的框架是 ExtJs(也是原型),它具有清晰简单的语法并支持静态方法。巨大的代码库和许可证(GPL,商业)使我无法使用相同的代码编写小型预算项目,这让我很恼火,我编写了一个基于 MIT 许可证的类管理器,称为 Esf-Core,用于核心类加载器功能(@987654321 @) 类似于 ExtJS 的编码风格。这是一个如何使用它的示例:

Esf.define('A', {
    a: null,

    constructor: function (a) {
        // Save var
        this.a = a;

        // Heyho
        console.log('A');
    },
    foo: function (b) {
        console.log('foo - ' + b);
    }
});

Esf.define('B', {
    b: null,

    constructor: function (a, b) {
        // Call super constructor
        this.callParent(a);

        // Save var
        this.b = b;

        // Heyho
        console.log('B');
    },
    foo: function () {
        this.callParent('bar');
    }
}, {
    extend: 'A'
});

// Use
var b = new B(1, 2);

// or
var b = Esf.create('B', 1, 2);

/*
 * Output:
 * A
 * B
 * foo - bar
 */
b.foo();

静态方法尚未实现,但会在不久的将来实现(如果您愿意,您可以自己实现,它只是一段代码),同时也是一个用于动态加载依赖项的类加载器。还在进行中的主框架也会带来基于主干的依赖注入和模型存储等。

如果您在此处看到,还有多种其他更轻量级的方式可以做到这一点:javascript inheritance framework(线程结束)

这里是静态方法的 ExtJS 方式:

Ext.define('Computer', {
     statics: {
         factory: function() {
             // This refers to the class not the object in static context
             return this.factory;
         }
     },

     factory: 'Unknown',
});

Ext.define('PC', {
     extends: 'Computer',

     factory: 'Dell',
});

// Dell
console.log(PC.factory());

代码应该可以工作,但我没有尝试 :-)

【讨论】:

  • 对于如此简单的事情来说太复杂了……真是令人失望。如果没有更好的办法,我想我将不得不接受这个。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-10
  • 1970-01-01
  • 1970-01-01
  • 2013-05-09
  • 2023-03-14
  • 2010-10-06
相关资源
最近更新 更多