简体   繁体   中英

jQuery plugin using reveal prototype pattern

I'm developing a jQuery plugin using the reveal prototype pattern, I'm having some trouble to instantiate my object. Below, the code of the plugin :

(function($) {

var GammadiaCalendar = function(elem, options) {
    this.elem = elem;
    this.$elem = $(elem);
    this.options = options;
};

GammadiaCalendar.prototype = function() {

    var defaults = {
        message: 'Hello world!'
    },

    init = function() {

        this.config = $.extend({}, this.defaults, this.options);

        this.displayMessage();

        return this;
    },

    displayMessage = function() {
        alert(this.config.message);
    };

    return {
        displayMessage : displayMessage
    };


};

GammadiaCalendar.defaults = GammadiaCalendar.prototype.defaults;

$.fn.GammadiaCalendar = function(options) {
    return this.each(function() {
        new GammadiaCalendar(this, options).init();
    });
};

})(jQuery)

I'm getting GammadiaCalendar is not defined when instantiating:

var gc = new GammadiaCalendar('id');

The problem is that you've set up the prototype as a function expression, and not as an immediately invoked function expression . You need to change it:

GammadiaCalendar.prototype = (function() {
   // your code here
})(); // Execute it

Furthermore, this line would never work:

GammadiaCalendar.defaults = GammadiaCalendar.prototype.defaults;

because defaults is never returned to the prototype.

Your whole structure of the revealing prototype pattern is incorrect. The init function, which is used by new GammadiaCalendar(this, options).init() , is private, and thus inaccessible. Therefore, the prototype needs to change to something like this:

GammadiaCalendar.prototype = (function() {
  var defaults = {
     message: 'Hello world!'
  },
  init = function() {
    this.config = $.extend({}, this.defaults, this.options);
    this.displayMessage();
    return this;
  },
  displayMessage = function() {
    alert(this.config.message);
  };

  return {
    defaults: defaults,
    init: init,
    displayMessage : displayMessage
  };

})(); 

(but of course, by doing it this way you haven't really gained anything with this pattern, since there are no real private functions inside anymore).

I don't see any point in that pattern, you could just do this:

(function($) { //Because of this, everything here is "private" unless exposed anyway

    var defaults = {
            message: 'Hello world!'
    };

    function init() {
        this.config = $.extend({}, defaults, this.options);

        this.displayMessage();

        return this;
    }

    var GammadiaCalendar = function(elem, options) {
        this.elem = elem;
        this.$elem = $(elem);
        this.options = options;
    };

    GammadiaCalendar.prototype = {

        displayMessage: function() {
            alert(this.config.message);
        },

        constructor: GammadiaCalendar
    };


    GammadiaCalendar.defaults = defaults;

    $.fn.GammadiaCalendar = function(options) {
        return this.each(function() {
            var instance = new GammadiaCalendar(this, options);
            init.call(instance);
        });
    };

})(jQuery);

Note that you can't do var gc = new GammadiaCalendar('id'); outside of the containing function because it is not exposed

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM