Mootools扩展mutator,从嵌套对象中的函数调用this.parent

时间:2012-11-03 01:22:07

标签: class inheritance mootools

这是一个如何使用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

不幸的是,我的Mootools Fu不是很强大,所以我有点不知所措。这可能与Extends目前的工作方式有关吗?如果不是,那么我想开始实现一个解决方案来做到这一点,但是我需要一些指示来让我开始正确的方向(制作一个自定义的Mutator?修改Core源?还有其他什么?)。任何关于如何进行的建议或想法将不胜感激。

更新

我想出了一种使用基于模式的mutator(Github)来做到这一点的方法。需要包含Mark的代码以便以下工作:

(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模式只是一个用单个下划线包围的键名(例如: _ 方法 _ )。类构造函数中的嵌套对象可以包含属性和方法的任意组合或其他嵌套对象。每个单独的对象都可以拥有一个带有“继承”键的属性,该属性具有以下值:'implements','extends'或false。实现和扩展对应于Implements和Extends Mootools类mutator的行为。 Extends是默认值,是为继承属性提供任何内容时使用的方法。值false将使给定对象(以及嵌套在其中的任何对象)保持完全继承。

可以找到包含示例的整个代码here

0 个答案:

没有答案