使用继承模式组织大型 jQuery 应用程序 - 如何扩展插件?

Using Inheritance Patterns to Organize Large jQuery Applications - how to extend the plugin?

我发现 this working example 的继承模式将业务逻辑和框架代码分开。我很想将它用作样板,但既然它是一个继承模式,那么我如何扩展业务逻辑(var Speaker中的方法)?

例如,如何将 walk: 方法扩展到其中?

/**
 * Object Speaker
 * An object representing a person who speaks.
 */
var Speaker = {
    init: function(options, elem) {
        // Mix in the passed in options with the default options
        this.options = $.extend({},this.options,options);

        // Save the element reference, both as a jQuery
        // reference and a normal reference
        this.elem  = elem;
        this.$elem = $(elem);

        // Build the dom initial structure
        this._build();

        // return this so we can chain/use the bridge with less code.
        return this;
    },
    options: {
        name: "No name"
    },
    _build: function(){
        this.$elem.html('<h1>'+this.options.name+'</h1>');
    },
    speak: function(msg){
        // You have direct access to the associated and cached jQuery element
        this.$elem.append('<p>'+msg+'</p>');
    }
};


// Make sure Object.create is available in the browser (for our prototypal inheritance)
// Courtesy of Papa Crockford
// Note this is not entirely equal to native Object.create, but compatible with our use-case
if (typeof Object.create !== 'function') {
    Object.create = function (o) {
        function F() {} // optionally move this outside the declaration and into a closure if you need more speed.
        F.prototype = o;
        return new F();
    };
}

$.plugin = function(name, object) {
    $.fn[name] = function(options) {
        // optionally, you could test if options was a string
        // and use it to call a method name on the plugin instance.
        return this.each(function() {
            if ( ! $.data(this, name) ) {
                $.data(this, name, Object.create(object).init(options, this));
            }
        });
    };
};

// With the Speaker object, we could essentially do this:
$.plugin('speaker', Speaker);

有什么想法吗?

简单地使用 JavaScript 的常规原型继承怎么样?

考虑一下:

function Speaker(options, elem) {
    this.elem = $(elem)[0];
    this.options = $.extend(this.defaults, options);

    this.build();
}
Speaker.prototype = {
    defaults: {
        name: "No name"
    },
    build: function () {
        $('<h1>', {text: this.options.name}).appendTo(this.elem);
        return this;
    },
    speak: function(message) {
        $('<p>', {text: message}).appendTo(this.elem);
        return this;
    }
};

现在您可以:

var pp = new Speaker({name: "Porky Pig"}, $("<div>").appendTo("body"));
pp.speak("That's all folks!");

Speaker.prototype.walk = function (destination) {
    $('<p>', {
        text: this.options.name + " walks " + destination + ".",
        css: { color: "red" }
    }).appendTo(this.elem);
    return this;
}

pp.walk("off the stage");

可运行版本:

function Speaker(options, elem) {
    this.elem = $(elem)[0];
    this.options = $.extend(this.defaults, options);

    this.build();
}
Speaker.prototype = {
    defaults: {
        name: "No name"
    },
    build: function () {
        $('<h1>', {text: this.options.name}).appendTo(this.elem);
        return this;
    },
    speak: function(message) {
        $('<p>', {text: message}).appendTo(this.elem);
        return this;
    }
};

var pp = new Speaker({name: "Porky Pig"}, $("<div>").appendTo("body"));
pp.speak("That's all folks!");
   
Speaker.prototype.walk = function (destination) {
    $('<p>', {
        text: this.options.name + " walks " + destination + ".",
        css: { color: "red" }
    }).appendTo(this.elem);
    return this;
}

pp.walk("off the stage");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>