1

Extends mutator の使用方法の簡単な例を次に示します。

var firstClass = new Class({
    aMethod: function(){
        console.log('firstClass method');
    }
});


var secondClass = new Class({
    Extends:firstClass,
    aMethod: function(){
        this.parent();
        console.log('secondClass method');
    },
    initialize: function(){
        this.aMethod();
    }
});

var instance = new secondClass();

//Output:
//      firstClass method
//      secondClass method

同じ動作を実現したいのですが、次のようなクラス コンストラクターを使用します。

var firstClass = new Class({
    methods: {
        aMethod: function(){
            console.log('firstClass method');
        }
    }
});


var secondClass = new Class({
    Extends:firstClass,
    methods: {
        aMethod: function(){
            this.parent();
            console.log('secondClass method');
        }
    },

    initialize: function(){
        this.methods.aMethod.call(this);
    }
});

var instance = new secondClass();

//Output:
//      Error: The method "initialize" has no parent.

instance.methods.aMethod.call(this);

//Output:
//      TypeError: this.parent is not a function

残念ながら私のムーツールズ・フーはあまり強くないので、ちょっと途方に暮れています。これは、Extends が現在動作している方法で可能ですか? そうでない場合は、これを行うためのソリューションの実装に取り​​組みたいと思いますが、正しい方向に進むためにいくつかの指針が必要です (カスタム Mutator を作成しますか? Core ソースを変更しますか? 他の何か?)。続行する方法についての提案やアイデアをいただければ幸いです。

アップデート

パターンベースのミューテーター ( Github )を使用してこれを行う方法を思いつきました。以下を機能させるには、マークのコードを含める必要があります。

(function(){

    /* Utility functions */

    Object.extend({
        containsMethods:function(obj){
            if(typeOf(obj) != 'object') return false;
            return Object.getLength(Object.filter(obj, function(item){return typeOf(item) == 'function';})) > 0;
        },

        containsObjects:function(obj){
            if(typeOf(obj) != 'object') return false;
            return Object.getLength(Object.filter(obj, function(item){return typeOf(item) == 'object';})) > 0;
        }
    });

    var getInheritance = function(obj, key){
        var temp = {};
        if(obj){
            if(obj.inheritance !== undefined){
                temp[key] = obj.inheritance;
            }
            delete obj.inheritance;
        }
        return temp;
    }

    /* Recursive function to turn specially keyed object literals in the constructor into class instances with inheritance */

    var classify = function(obj, inherit, key, imap){
        if(typeOf(obj) != 'object'){return obj;}

        if(key == undefined){
            key = '';
        }

        var inheritance = 'extends';

        if(imap != null){
            imap = Object.append(imap, getInheritance(obj, key));
            imap = Object.append(imap, getInheritance(inherit, key));

            if(imap[key] != undefined){
                inheritance = imap[key];
            }
        }

        var i = 'extends';

        for(var k in inherit){
            if(!inherit.hasOwnProperty(k)) {continue;}

            i = 'extends';

            if(imap != null){

                if(typeOf(inherit[k]) == 'object'){
                    imap = Object.append(imap, getInheritance(inherit[k], k));
                }

                if(typeOf(obj[k]) == 'object'){
                    imap = Object.append(imap, getInheritance(obj[k], k));
                }                   

                if(imap[k] != undefined){
                    i = imap[k];
                }
            }

            /* Needed to clean up properties when inheritance == false */
            if(inherit[k] === undefined){
                delete inherit[k];
            }

            if(typeOf(inherit[k]) == 'object' && i === false && !Object.keys(obj).contains(k)){
                obj[k] = undefined;
                continue;
            }

            if(obj[k] && typeOf(obj[k]) == 'object' && i !== false){
                obj[k] = classify(obj[k], inherit[k], k, imap);
            }
        }

        if(Object.containsMethods(obj)){
            var constructor = {};

            if(inherit != undefined && inheritance !== false){

                if(inheritance == 'implements'){
                    constructor.Implements = (inherit.$constructor ? inherit.$constructor : new Class(inherit));
                }else {
                    constructor.Extends = (inherit.$constructor ? inherit.$constructor : new Class(inherit));
                }
            }

            obj = new (new Class(Object.append(constructor, obj)));

        }else {

            if(!Object.containsMethods(inherit)){
                obj = Object.append({}, inherit, obj);
            }
        }

        return obj;
    };

    /* Mutator */

    Class.defineMutator(/^_(\w+)_/, function(params, key){
        var old_key = key;
        var key = key.replace(/_/g, "");
        var c = null;
        var imap = null;

        if(this.$constructor){
            imap = this.$constructor.imap = (this.$constructor.imap || {});
        }

        if(this.prototype[key] != undefined){
            c = classify.call(this, params, this.prototype[key], '', imap);
        }else {
            c = classify.call(this, params, undefined, '', imap);
        }

        this.prototype[key] = c;
        delete this[old_key];
    });

})();

mutator パターンは、1 つのアンダースコアで囲まれた単純なキー名です (例: _ methods _ )。クラス コンストラクターのネストされたオブジェクトには、プロパティとメソッドの任意の組み合わせ、または他のネストされたオブジェクトを含めることができます。個々のオブジェクトはそれぞれ、「implements」、「extends」、または false の値を取る「inheritance」キーを持つプロパティを持つことができます。Implements と extends は、Implements と Extends Mootools クラスのミューテーターの動作に対応します。Extends がデフォルトであり、継承プロパティに何も指定されていない場合に使用されるメソッドです。false の値は、指定されたオブジェクト (およびその中にネストされているすべてのオブジェクト) が完全に継承されないようにします。

例を含むコード全体はここにあります

4

0 に答える 0