Override privileged method of base class

前端 未结 2 931
没有蜡笔的小新
没有蜡笔的小新 2020-12-25 09:17

How can I go about making a child class override a privileged method of a base class?

If its not possible, is there another way to achieve what I am trying to accomp

2条回答
  •  庸人自扰
    2020-12-25 09:23

    IMO, you need to use a Javascript library like Ext Js to simplify this task. Anyway, the following example illustrates how you can write some helper methods. It's a part of an unreleased open source project that I'm working on.

    var JWObject = (function () {
    
        var jwobj = function (){};
    
        jwobj.prototype = { };
    
        return jwobj;
    
    })();
    
    var Prototype = (function () {
    
        var scopeQueue = [ window ];
    
        return {
    
            beginScope: function (namespace) {
                var parts = namespace.split('.');
                for (var i = 0; i < parts.length; i++) {
                    var name = parts[i],
                        parent = this.getScope(),
                        part = parent[name];
    
                    if (part && !part.__namespace) {
                        throw Error('/* ERROR MESSAGE */');
                    }
    
                    scopeQueue.push(parent[name] = (part || { __namespace: true }));
                }
            },
    
            endScope: function () {
                if (scopeQueue.length > 1) {
                    scopeQueue.pop();
                }
            },
    
            getScope: function () {
                return scopeQueue.pick();
            },
    
            define: function (name, members) {
    
                var scope = this.getScope();
    
                if (scope[name]) {
                    throw Error('The prototype already exist.');
                }
    
                this.extend(members, {
                    scope: scope,
                    extend: JWObject,
                    statics: {}
                });
    
                // Getting constructor
                var ctor = (members.constructor === Object) ? function() { } : members.constructor;
                delete members.constructor;
    
                if (typeof members.extend === 'string') {
                    members.extend = scope[members.extend];
                }
    
                if (!members.extend) {
                    throw Error('The base class is not specified.');
                }
    
                // Deriving from parent type
                ctor.prototype = new members.extend();
                members.super = members.extend.prototype;
                delete members.extend;
    
                members.statics.__class = true;
                this.extend(ctor, members.statics, true);
                delete members.statics;
    
                // Adding new members
                this.extend(ctor.prototype, members, true);
    
                // Adding and returning the created prototype
                return scope[name] = ctor;
    
            },
    
            extend: function (expando, members, override) {
                for (var m in members) {
                    if (override || !expando[m]) {
                        expando[m] = members[m];
                    }
                }
            }
    
        };
    
    })();
    
    Prototype.extend(Array.prototype, {
    
        pick: function() {
            return this[this.length - 1];
        }
    
    });
    

    Here is the result:

    Prototype.beginScope('Sample');
    
    /**
     * Prototype: Sample.Plugin
     */
    Prototype.define('Plugin', {
    
        init: function() {
            alert('init!');
        }
    
    });
    
    Prototype.beginScope('Extension');
    
    /**
     * Prototype: Sample.Extensions.Plugin
     * Extend   : Sample.Plugin
     */
    Prototype.define('Foo', {
        extend: Sample.Plugin,
    
        init: function() {
            this.super.init.call(this);
            alert('child: init!');
        },
    
        fun: function() {
            this.init();
        },
    
        statics: {
    
            create: function() {
                return new Sample.Extension.Foo();
            }
    
        }
    
    });
    
    Prototype.endScope();
    Prototype.endScope();
    

    As you can see in the preceding code, the Prototype object provides some functionality to defining a namespace (Prototype.beginScope, Prototype.endScope and Prototype.getScope) or defining a prototype (Prototype.define).

    You can inherit a prototype from another using extend like java.

    Prototype.define('Foo', {
        extend: Sample.Plugin,
    

    Or call the base class method as follows:

        init: function() {
            this.super.init.call(this);
    

    Also, every prototype you define with above code will be derived from JWObject by default.

提交回复
热议问题