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– outis2015年07月16日 22:18:02 +00:00Commented Jul 16, 2015 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– null2015年07月16日 22:22:47 +00:00Commented Jul 16, 2015 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– turbo2oh2015年07月16日 22:46:36 +00:00Commented Jul 16, 2015 at 22:46
-
@outis thanks, yeah I should probably start with the stripped down version and add that if needed.turbo2oh– turbo2oh2015年07月16日 22:50:44 +00:00Commented Jul 16, 2015 at 22:50
-
1Possible duplicate of Are there any OO-principles that are practically applicable for Javascript?Greg Burghardt– Greg Burghardt2016年11月02日 03:12:49 +00:00Commented Nov 2, 2016 at 3:12
1 Answer 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(...);