I have been using a pattern similar to this basic structure below. Can anyone please let me know if this is a correct way to code an object-oriented widget for reuse?  I am looking to make code than can also be extended easily and modular.$(function(){// wrap in jquery .fn wrapper so that may be called on afunction $lider(autoplay, velocity, controls){  var $lider = [    // props n methods, accessible through data-slider-* attributes    {       settings : {         envokeBecause : $('[data-widget~=slider]'),        autoplay : autoplay,        speed : velocity,        showControls : controls,        slideSize : '100%',// 25% will show 4 slides if the parent container is 100% width and so on      },      bindings : {        slideRail : $('[data-function~=slide-rail]'),        slide : $('[data-function~=slide]'),        nextButton : $('[data-function~=next]'),        prevButton : $('[data-function~=prev]'),        playButton : $('[data-function~=play]'),        pauseButton : $('[data-function~=pause]'),        stopButton : $('[data-function~=stop]')        // attach this functionality to the DOM      },      methods : {        slideNext :  function(){ slideRail.animate({left: '-=100%'}, velocity)   },        slidePrev : function(){ slideRail.animate({left: '+=100%'}, velocity)  },        slideRestart : function(){ slideRail.animate({left: '0%'}, velocity)  },        slideStart :  function(){ window.$liderTimer = setInterval(slideNext, velocity) },        slidesCount : function(){ slideRail.children().size()        }      }    }  ]  $.each($lider, function(){    //  iterate through all of the slider objects properties    window.SliderProps = this;    // set slider to be accessible to the global scope  });  // slider props stored as vars  var $liderHook = SliderProps.settings.envokeBecause;  var slideRail = SliderProps.bindings.slideRail;  var slide = SliderProps.bindings.slide;  var play = SliderProps.bindings.playButton;  var next = SliderProps.bindings.nextButton;  var prev = SliderProps.bindings.prevButton;  var pause = SliderProps.bindings.pauseButton;  var stop = SliderProps.bindings.stopButton;  var slideCount = SliderProps.bindings.slideRail.children().size();  var slideCounter = 0;   function slidePrev(){    var slidePrev = SliderProps.methods.slidePrev();  }  function slideStop(){    /*slideRail.stop(); */    window.clearInterval( $liderTimer  )  }  function slideRestart(){    var slidePrev = SliderProps.methods.slideRestart();    slideRail.stop();   }  function autoPlay(){    SliderProps.methods.slideStart();   }  function slideNext(){    slideCounter++    var slideNext = SliderProps.methods.slideNext();    console.log(slideCounter)      console.log(slideCount)    if (slideCounter != slideCount){      // offset var-1 for js index compensation      console.log('keep slidin..')    }    else {      console.log('stop!')      slideRestart();      slideCounter = 0;    }  }  // element -> event delegation type -> function()  slideRail.hover( slideStop )  next.click( slideNext )  prev.click( slidePrev )  stop.click( slideRestart )  pause.click( slideStop )  play.click( autoPlay )} // close function slider()$lider(true, 750);}); 
Object-oriented widget for reuse
javascript;jquery;object oriented
I'd suggest taking a look at jquery-boilerplate, especially the jqueryUI widget portion.I started refactoring your code in a true $widget manner. It's not completely functional but should point you in the right direction. ;(function ( $, window, document, undefined ) {  $.widget(yourCustomNamespace.slider, {    /*     * Options to be used as defaults:     */    options: {      autoplay: true,      controls: true,      duration: 750,      slideSize: '100%',      selectors: {        slideRail: '[data-function~=slide-rail]',        slide: '[data-function~=slide]',        next: '[data-function~=next]',        prev: '[data-function~=prev]',        play: '[data-function~=play]',        pause: '[data-function~=pause]',        stop: '[data-function~=stop]'      }    },    /*     * Private Methods:     */    _create: function() {      this._setOption(current, 0);      this._setOption(total, this.element.children().length);      this._on(this.element, {        hover  + this.options.selectors.slideRail: $.proxy(this.stop, this),        click  + this.options.selectors.next: $.proxy(this.next, this),        click  + this.options.selectors.prev: $.proxy(this.prev, this),        click  + this.options.selectors.stop: $.proxy(this.stop, this),        click  + this.options.selectors.pause: $.proxy(this.pause, this),        click  + this.options.selectors.play: $.proxy(this.play, this)      });      if(this.options.autoplay) {        this.start();      }    },    _destroy: function() {      this._off(this.element, click hover);    },    _setOption: function(key, value) {      switch (key) {        case current:          // Update internal object ...          this.options[key] = value;          // Update DOM ...          // this.element.find(this.options.selectors.slideRail.animate({...}, this.options.duration) ...          break;        default:          this.options[key] = value;          break;      }      return this._super(_setOption, key, value);    },    /*     * Public Methods:     */    next: function() {      // TODO: Account for overflow, this.options.total      this._setOption(current, this.options.current + 1);    },    prev: function() {      // TODO: Account for underflow, this.options.total      this._setOption(current, this.options.current -1);    },    restart: function() {      this._setOption(current, 0);    },    start: function() {      this.interval = window.setInterval($.proxy(this.next, this), this.options.duration);    },    stop: function() {      window.clearInterval(this.interval);    },    getCount: function() {      return this.options.total;    }  });})( jQuery, window, document );ReferenceThere are a couple of things regarding reusability going on in here:options are your default parameters that can be overwritten on initializing a new widget instance, e.g. $('[data-widget~=slider]').slider({autoplay: false}); would overwrite the default of autoplay: trueEvent binding is handled internally via this._on()Ideally the widget would manage its own application state logic via this._setOption(). That way you can distinguish between logic and DOM interaction. Whenever a value changes, you update the DOM accordingly. You can call public methods from other places via the automatic interface the widget provides, e.g. $('[data-widget~=slider]').slider(next)