-1

I'm quite experienced with jQuery but I'm just getting into object oriented Javascript and want to make sure I'm doing it right.

Here's an example of what I'm doing so far... I'd appreciate tips/advice on how I can improve my approach:

// create a class for collapsable fieldsets
window.CollapsableFieldset = (function() {
  function CollapsableFieldset(jQObject) {
    // look for all the legend tags within this fieldset
    jQObject.find("legend").click(function(event) {
      // add or remove the "open" class to the fieldset
      return jQObject.toggleClass("open");
    });
  }
  return CollapsableFieldset;
})();

jQuery(document).ready(function() {
  return $("fieldset.collapsable").each(function(i, element) {
    return new CollapsableFieldset($(element));
  });
});

So basically I'm creating a class that defines the behaviour I'm looking for and then in the jQuery block, I'm selecting each object that matches and creating a new instance of the class with that object as an argument.

3 Answers 3

1

This is not object-oriented javascript.

Before getting into prototyping, let me make one remark: your use of a closure in CollapsableFieldset is unnecessary and cumbersome. Indeed, you do not have any variables in the (function(){})() pattern. You may rewrite, without any loss, to:

window.CollapsableFieldset = function (jQObject) {
  jQObject.find('legend').click(function(event) {
    return jQObject.toggleClass('open');
  });
}

Now, you create classes in javascript using a function constructor, in which the "this" keyword defines the object that a "new" statement will yield:

function CollapsableFieldset (jQObject) {
  // This is the function constructor.
  this.field = jQObject;
}
CollapsableFieldset.prototype.findAndToggle = function (tag, cssclass) {
  // This defines a method "findAndToggle" on the CollapsableFieldset type.
  this.field.find(tag).click(function(event) {
    return this.field.toggleClass(cssclass);
  });
};

jQuery(document).ready(function() {
  return $("fieldset.collapsable").each(function(i, element) {
    var colFieldset =  new CollapsableFieldset($(element));
    return colFieldset.findAndToggle('legend', 'open');
  });
});

Please bear in mind that object-oriented javascript is not always the optimal solution.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks a lot for your input... the function wrapper wasn't my idea - I actually write my JS in coffeescript now which does some extra wrapping and adds extra returns etc. You mention that OO Js is not always the optimal solution... is there a best-practice for jQuery? I really don't like sticking all of my code inside that one jQuery() function - it gets harder to maintain as it gets bigger
If you worry about having too many variables in the same scope, you can organize your code into a collection of functions. You can even define functions inside other functions, and use functions that encapsulate a state with closures.
what about grouping related functions together and sticking them into an object - then calling them as object methods. Eg: commentsForm.load() // loads all jQuery related to the comments form?
0

One option would be to use Jquery UI's widget factory and encapsulate behaviour in widgets. http://wiki.jqueryui.com/w/page/12138135/Widget-factory

Comments

0

You are using an immediately called function expression for no good reason, your code is functionally equivalent to:

  function CollapsableFieldset(jQObject) {
    // look for all the legend tags within this fieldset
    jQObject.find("legend").click(function(event) {
      // add or remove the "open" class to the fieldset
      return jQObject.toggleClass("open");
    });
  }

The "constructor" doesn't return the object created when it is called with new, no advantage it taken of prototype inheritance so no point to using new.

The object returned by the function isn't assigned to anything, so what's the point of returning anything?

> jQuery(document).ready(function() {  
>     return $("fieldset.collapsable").each(function(i, element) {
>         return new CollapsableFieldset($(element));
>     });
> });

Where does the object returned by new CollapsableFieldset(...) go?

Incidentally, there is no point to creating global variables using:

window.varName...

when

var varName ...

does it so much better.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.