0

私は現在、非常に大きなアクション スクリプト ライブラリを変換して、私の nodejs プロジェクトで動作するようにしています。そうしているうちに、問題になる可能性のある何かに出くわしました: クラスからクラスを構築することです。

オブジェクトを別のオブジェクトのベースとして使用する方法はありますか (IE: ベース オブジェクトからすべてのメンバーを継承し、拡張オブジェクトから同じ名前のメンバーを上書きします)?

現在、これが私が行っていることですが、3 つ以上のクラスが重ねて構築されているため、管理が少し難しくなっています。

// The base object which others may extend
function A() {
    this.a = "pie";
}
A.prototype.yum = function() {
    return this.a + " is AWESOME!";
}

// The "extends A" object.
// Instead of creating an instance of "B", I current just create an instance of "A",
// then adding the members from "B" to it at which point I return the "A" instance.
function B() {
    var a = new A();
    a.b = "pie";
    // Notice how I have to declare the overwriting function here instead of being able 
    // to drop it into B's prototype. The reason this bothers me is instead of just
    // having one copy of the function(s) stored, each time a "new B" is created the
    // function is duplicated... for 100s of "B" objects created, that seems like poor
    // memory management
    a.yum = function () {
        return "I like " + this.a + " and " + this.b;
    };
    return a;
}
console.log((B()).yum());




以下に沿って何かをすることは可能ですか?
私はこれが有効ではないことを知っていますが、アイデアを提供します。

function A(){
    this.a = "pie"
}
A.prototype.yum = function () {
    return this.a + " is AWESOME!";
}
function B(){
    // Throws an "illegal left hand assignment" Exception due to overwriting `this`;
    this = new A();
    this.b = "cake"
}
B.prototype.yum = function () {
    return "I like "+this.a+" and "+this.b;
}
console.log((new B()).yum());

注:
1: JavaScript にはクラスがないことはわかっています。オブジェクトとプロトタイプを使用します。そうでなければ、私は尋ねません。
2: これは変換しようとしている実際のコードではありません。これは一般化された例です
3: ライブラリを提案しないでください。時にはそれらが価値があることは知っていますが、プロジェクトのライブラリ全体を維持し、依存し、含める必要はありません。



ANSWER : ネイティブ メンバーのプロトタイプを変更するのは悪いことだとは思いますが、可能な機能が不足していることと、そのサイズを考えると、これはメリットがあると思います。

Object.prototype.extendsUpon = function (p) {
    var h = Object.prototype.hasOwnProperty;
    for(var k in p)if(h.call(p,k))this[k]=p[k];

    function c(c){this.constructor=c;}
    c.prototype = p.prototype;
    this.prototype = new c(this);
    this.__base__ = p.prototype;
}


function object_Constructor_built_ontop_of_another_constructor() {
    this.extendsUpon(base_Object_to_built_atop_off);
    this.__base__.constructor.apply(this, arguments);

    // From here proceed as usual

    /* To access members from the base object that have been over written,
    * use "this.__base__.MEMBER.apply(this, arguments)" */
}
4

1 に答える 1

1

非常に可能です。あなたは複数の方法でそれを行うことができます.coffeescriptでより完全に使用されます:

    var ClassBase, ClassTop,
      __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; };

    ClassBase = (function() {

      function ClassBase() {}

      return ClassBase;

    })();

    ClassTop = (function(_super) {

      __extends(ClassTop, _super);

      function ClassTop() {
        return ClassTop.__super__.constructor.apply(this, arguments);
      }

      return ClassTop;

    })(ClassBase);

定型コードがいくつかあります。ClassTopからすべてを継承していClassBaseます。__extendクラスには、 、 a 、(function(_super...およびいくつかのコンストラクターのボイラープレート以外の内部にはあまりありませんが、かなり単純です。

継承はほとんどの場合、__extendsいくつかの魔法を行うボイラープレートによって管理されます。完全な__extends方法はここで美化されています:

    __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;
    };

繰り返しますが、以前よりもはるかに怖くなくなりました。基本的に、親が持つプロパティをチェックして、それらを子に適用しています。詳細については、http ://www.jimmycuadra.com/posts/coffeescript-classes-under-the-hood をご覧ください。

于 2012-11-12T07:40:49.243 に答える