Last active
December 16, 2015 01:30
-
-
Save marcelbeumer/5355872 to your computer and use it in GitHub Desktop.
JavaScript Coding Guidelines
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// guide.js | |
// ======== | |
// Description of this file. | |
// In case of AMD | |
define( | |
['jquery', 'underscore', 'EventEmitter', 'AnotherClass'], | |
function($, _, EventEmitter, AnotherClass) { | |
"use strict"; | |
// We put the following jshint/global directives in a | |
// project wide .jshintrc instead of at the top of our | |
// sources to keep things clean and maintainable | |
/*jshint undef:true, forin:false, eqeqeq:true, browser:true, node:true, devel:true, newcap:true */ | |
/*global define:true */ | |
// We don't indent here, because otherwise our entire file | |
// is indented, no thanks! | |
// General stuff | |
// ------------- | |
// - softtabs, 4 spaces | |
// - 2 whitelines between each function/method | |
// - jshint (see header) passing, always. | |
// - Lines are <= 80char | |
// utilFunctionA | |
// ------------- | |
// Describe this here shortly. Note: util function that don't fit | |
// in a class method, we put in here. | |
function utilFunctionA() { | |
// ...... | |
} | |
// MyClass < BaseClass | |
// ------------------- | |
// Brief description of what this thing does. | |
// This, for example, takes a string and a Rainbow | |
// and makes an instance of a Unicorn | |
// | |
// The < in the title means that MyClass inherits from BaseClass | |
// | |
// + params | |
// - someString (String) - a string with the unicorns name | |
// - rainbow (Rainbow) - a Rainbow object | |
// + returns | |
// - (Unicorn) - returns a new unicorn instance | |
function MyClass(name, rainbow) { | |
// All variables are at the top of the function. | |
var obj, | |
elements, | |
something, | |
otherThingFromElement, // Rather a bit too verbose, than too short. | |
value, | |
x, l, el; // Unless it is really obvious | |
// Initialize all properties inside the constructor, even when null | |
this.counter = 0; | |
this.title = null; | |
// In case you want to be sure that all methods are always executed within | |
// the scope of this instance, we do a bindAll. This is typically needed | |
// when directly using instance methods as event handlers of DOM elements. | |
_.bindAll(this); | |
// Do stuff | |
l = elements.length; | |
for (x = 0; x < l; x++) { | |
el = elements[x]; | |
if (something === el) { // Always triple === | |
// When something does not fit within 79 char, we break and | |
// give a *double* indent, Python style. | |
otherThingFromElement = | |
something.getClassesTheFastestWayPossible(true, false, true); | |
// We are not afraid of comments. | |
value = x > 0 ? "a" : "b"; | |
} | |
} | |
if (true) { | |
// ... | |
} else if (true) { | |
// ... | |
} else { | |
// ... | |
} | |
// When short and readable, chain on a single line | |
$("body").remove().end().find(); | |
// When long or less readable, we can indent like this | |
$("foo") | |
.dsadas() | |
.dasdsadas() | |
.adasdasdas() | |
.dasdasdas(); | |
} | |
// Inheritance | |
_.inherits(MyClass, AnotherClass); | |
// ### Public MyClass :: myMethod | |
MyClass.prototype.myMethod = function(el) { | |
// Often it is easy and clean to pass event handler like this | |
$(el).click(this.handleSaveButton); | |
}; | |
// ### Public MyClass :: myOtherMethod | |
MyClass.prototype.myOtherMethod = function(el) { | |
var self = this; | |
// But sometimes you might want to use self, and that is fine too, | |
// as long as we choose the most readable option | |
$(el).click(function() { | |
$(this).removeClass('never-touched'); | |
self._updateInternalCounter(); | |
}); | |
}; | |
// ### Public MyClass :: handleSaveButton | |
// When a method is an event handler, we name methods like "handle<Something". | |
// This allows to directly el.click(this.handleSaveButton); | |
MyClass.prototype.handleSaveButton = function(e) { | |
e.preventDefault(); | |
}; | |
// ### Private MyClass :: updateInternalCounter | |
// We mark methods as private with _. Methods are marked private only when they | |
// are really obviously private and default to public, to prevent having those | |
// underscores all over the place. | |
MyClass.prototype._updateInternalCounter = function() { | |
this.counter++; // We are perfectly fine with ++ | |
}; | |
// Export | |
return MyClass; | |
}); | |
// In case of non-AMD | |
(function () { | |
"use strict"; | |
// Note: at the top of the file, we define things we are going to use more | |
// often in this file, like you would with CommonJS require or Python imports | |
var global = window, | |
$ = global.jQuery, _ = global._, | |
EventEmitter = global.EventEmitter2, | |
AnotherClass = global.AnotherClass; | |
// The rest except for returning something. | |
// Instead, we might expose manually, like: | |
global.MyClass = function(){}; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment