5

I have some code that I'm refactoring, right now its just a list of functions, primarily jQuery.

The code is a form builder. The user adds sections, questions etc using jqueryUI drag/drop/sort. They can get quite long in the range of > 1k questions. I've been debating between patterns,frameworks, etc. and have settled on what I believe will be the best improvement without ripping everything out and starting completely over with something like angular or react.

I was also considering the module pattern but I'm concerned about having so many duplicates of the methods in memory (>1k) and thought this might serve me better. Is there anything I'm overlooking or gotchas that might cause an issue? I like that its all wrapped inside an IIFE and feels encapsulated.

Pattern example:

var Question = (function() {

    function Question(name, type) {
        // enforces new
        if (!(this instanceof Question)) {
            return new Question(name,type);
        }

        // constructor body
        this.name = name || 'default' ;
        this.type = type || 'text';
    }

    Question.prototype.someMethod = function(arg) {
        // method body
    }

    return Question;
}());

it would be used like so:

Question question1 = new Question('name','picklist');
  • Will some cases have local variables/class private fields? If not, the outer anonymous function & var assignment can be done away with. – outis Jul 16 '15 at 22:18
  • I was about to abort reading your question and just dropping a comment about angular, but then you mentioned that you do not want to use it. I do not quite understand your reasoning about the necessity to rip everything apart, because angular is supposedly built to integrate well with other frameworks, it even includes a jQuery subset. You talk about patterns and frameworks (higher level abstractions), but your solution is nothing but a class in javascript. That's like answering "Are you using angular or jQuery?" with "no, variables work much better for me" – null Jul 16 '15 at 22:22
  • @null I suppose I shouldn't discount angular entirely. When I thought of angular I immediately thought of things like: dependency injection, directives, isolate scope, etc. Unfortunately I've only really played around with angular and am concerned about the ramp up time to learn/re-learn even the basics of the framework. If you were in my place would you still consider going this direction? – turbo2oh Jul 16 '15 at 22:46
  • @outis thanks, yeah I should probably start with the stripped down version and add that if needed. – turbo2oh Jul 16 '15 at 22:50
  • 1
1

The pattern you've cited in your example is just fine, although in your case, not really required. The idea of the module pattern is to hide away the things you don't explicitly return. So in your case, your IIFE isn't really doing anything (if you had private helpers inside your modules, however, you would).

If you have common methods which are shared among components (for example, all form elements may have a getValue() method, you can use JavaScript's prototypal inheritance to create a parent object, and have the various form elements inherit from it:

function FormObject() {}
FormObject.prototype.getValue = function() { return 42; };

function Question() {
    // ...
}
Question.prototype = Object.create(FormObject);
Question.prototype.constructor = Question;

This ugliness can be resolved with ES6's class feature, which is syntactic sugar to all of that:

class FormObject {
    // FormObject generic implementation here
}
class Question extends FormObject {
    constructor() {
        // ...
    }
    someMethod() {
        // ...
    }
}
var question1 = new Question(...);

Also, if you're into modules, have a look at Browserify and webpack. For ES6 today, have a look at Babel.

formObject.js

class FormObject {
    // FormObject generic implementation here
}
module.exports = FormObject;

question.js

var FormObject = require('./formObject');
class Question extends FormObject {
    constructor() {
        // ...
    }
    someMethod() {
        // ...
    }
}
module.exports = Question;

main.js

require('./question.js');
var question1 = new Question(...);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.