bigbite / code-guide Goto Github PK
View Code? Open in Web Editor NEWHow you should be writing code
How you should be writing code
Never extend the prototype of native objects, or overwrite native object properties.
(I stole the below example from somewhere)
var a = [];
if (!a.length) {
console.log('a is empty');
}
// not
Array.prototype.empty = function () {
return !this.length;
}
var a = [];
if (a.empty()) {
console.log('a is empty');
}
This is perhaps moreso for library-based code than otherwise; should we recommend returning an object, where possible, to allow method chaining?
How's aboot this?
You must leave a space before and after function parentheses:
function foo () {}
not function foo(){}
In an IIFE, it's okay not to space before & after the invokation parens; however, the declaration parens must still have the sapces:
(function () {
// do stuff
}());
Not wholly sold on this one, but it is something that I do. Thoughts?
It is preferred to use ES5 array loops, where applicable:
theArray.forEach(function (value, index) {
newArr.push([index, value]);
});
// instead of
var newArr = [],
i;
for (i = 0; i < theArray.length; i++) {
newArr[i] = [i, theArray[i]];
}
This is not a hard-and-fast rule, as there are valid use-cases for the latter method, but the former is much more semantic when applicable.
When performing object loops, you must wrap the loop body in an if
statement, to check that the current property is a member of the subject, and not an inherited property:
// function body
var prop;
for (prop in theObject) {
if (theObject.hasOwnProperty(prop)) {
// logic
}
}
To the best of my knowledge, there is literally no point in the jQuery Document Ready function $(document).ready(function () {});
or $(function () {});
; we always include our scripts in the footer so, by the time the script is parsed, the document is already fully parsed.
Since we've already agreed to wrap our code in an IIFE, anyway, I feel it would be more prudent to simply pass jQuery as an argument to that (which we probably would anyway).
NB:
Please don't confuse this with the jQuery $(window).load(function () {});
methodology - this event uses the window's (on)load
event, not DOMContentLoaded
. This API method can safely be wrapped inside of the IIFE.
Always use strict (in)equality operators.
a === b;
c !== d;
// not
a == b;
c != d;
When passing data to an event, pass an object, rather than a value; passing an object allows additional data to be added at a later date. i.e.
// pseudo code
// do this
var.fire('eventName', { item: value });
var.listen('eventName', function (event, data) {
// do something with `data.item`
});
// not this
var.fire('eventName', value);
var.listen('eventName', function (event, value) {
// do something with value
});
Should we go a mobile first approach rather than desktop first? Or should this be more project specific?
Some articles on it:
http://designshack.net/articles/css/mobilefirst/
http://www.wearejh.com/design/benefits-of-a-mobile-first-approach/
http://www.wearejh.com/design/benefits-of-a-mobile-first-approach/
Adding properties to an object by overwriting the prototype makes inheritance impossible; appending to a prototype means that all properties inherited from the parent are still accessible to the child (unless you're purposely overwriting a property -> something you shouldn't do, anyway, except in rare cases!).
function BigBite () {
console.log('foo');
}
// overwriting prototype
BigBite.prototype = {
staff: ['jason', 'mark', 'iain', 'natalie'],
addMember: function (name) {
this.staff.push(name);
}
};
// appending to prototype
BigBite.prototype.staff = ['jason', 'mark', 'iain', 'natalie'];
BigBite.prototype.addMember = function (name) {
this.staff.push(name);
};
I'm an option two
kinda guy.
// option one
var len = thing.length;
var i;
for (i = 0; i < len; i++) {
// do stuff
}
// option two
var len = thing.length;
var i = 0;
for (i; i < len; i++) {
// do stuff
}
// option 3
var len = thing.length;
var i = 0;
for ( ; i < len; i++) {
// do stuff
}
For projects not involving Angular, (i.e. WP projects), since Angular provides its own method of encapsulation, I propose wrapping code blocks in an IIFE; thoughts?
/*
* This is an Immediately-Invoked Function Expression, or IIFE.
* Wrapping code inside an IIFE provides encapsulation, so that
* the global scope is protected from pollution. Additionally,
* it provents naming collision between code blocks.
* Arguments listed within the function parentheses are passed
* in at the end of the expression.
*/
(function (win, doc, $) {
//code goes here
}(window, document, jQuery));
/*
* Any arguments to be passed to the function scope should be
* added within the parentheses after the closing curly brace.
* When jQuery is in use, pass the no-conflict variant of the
* `jQuery` object, rather than the `$` shorthand. `$` can be
* specified as the function parameter at the start of the
* expression.
* Passing `window` and `document` as parameters increases
* performance by saving lookups.
*/
If the project isn't using Angular or another framework then I think projects should include UnderscoreJS as standard as it helps a lot when working Arrays.
If arguments supplied (whether it be to a conditional or a function) result in large line lengths, it can be more readable to introduce line breaks. Which would be your preferred method:
// option zero
if (conditionOne() && conditionTwo() && conditionThree() && reallyLongConditionFourThatTakesUpALotOfSpace()) {
}
// option one
if (conditionOne() && conditionTwo() && conditionThree() &&
reallyLongConditionFourThatTakesUpALotOfSpace()) {
}
// option two
if (conditionOne() &&
conditionTwo() &&
conditionThree() &&
reallyLongConditionFourThatTakesUpALotOfSpace()) {
}
// option three
if (conditionOne() &&
conditionTwo() &&
conditionThree() &&
reallyLongConditionFourThatTakesUpALotOfSpace()
) {
}
// option four
if (
conditionOne() &&
conditionTwo() &&
conditionThree() &&
reallyLongConditionFourThatTakesUpALotOfSpace()
) {
}
// option five
if (
conditionOne() &&
conditionTwo() &&
conditionThree() &&
reallyLongConditionFourThatTakesUpALotOfSpace()) {
}
Some sites that could be useful to mash together ours:
https://www.npmjs.org/doc/coding-style.html
http://nodeguide.com/style.html
http://javascript.crockford.com/code.html
https://github.com/airbnb/javascript
https://github.com/rwaldron/idiomatic.js
http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml
http://seravo.fi/2013/javascript-the-winning-style
Variable names should always be in lowerCamelCase
, except in two instances:
UpperCamelCase
CAPS_SNAKE_CASE
Boolean vars should be set to true
or false
, don't use 1
and 0
unless you have good reason to
When intentionally setting/removing a value, you should set it to null
Never set values as undefined
We need a folder created for stuff like .editorconfig
that follows this style guide.
Majority verdict: _
prefix for private methods
I've just seen something on this, and it seems like a cool idea; going to have to try testing it.
Apparently one can have named closures:
var a = [a, b, c];
a.forEach(function loopy (v, i) {
// oooh, fancy
});
Variables should be instantiated using literal over constructor notation, in my opinion:
var scopeObjVar = {}, // empty object
scopeArrVar = []; // empty array
// instead of
var scopeObjVar = new Object(),
scopeArrVar = new Array();
All functions should be preceded by a docblock comment describing the function logic, its parameters, and its return value (if any).
/**
* grabs the header, does some funky stuff with it, and returns the object
* @param {jQuery object} selector the selector upon which we're performing logic
* @return {jQuery object} the selector in its new state
*/
function doSomething (selector) {
selector = selector || $('#header');
selector.height(50)
.width(60)
.addClass('sexy')
.fadeOut();
return selector;
}
When using curly braces, always open them on the same line as the statement.
function foo () {
// something
}
// not
function foo ()
{
// something
}
You should select elements by id
where possible. You should not select by data attributes.
http://jsperf.com/jquery-selector-perf-rthertheg
Here's a few different variations on a theme; it's an angular snippet, but it applies to any javascript. which is your preference?
angular.module('app')
.controller('AccountController', function ($scope, $state) {
$scope.stateData = $state.current.data;
});
angular
.module('app')
.controller('AccountController', function ($scope, $state) {
$scope.stateData = $state.current.data;
});
angular
.module('app')
.controller('AccountController', function ($scope, $state) {
$scope.stateData = $state.current.data;
});
angular.module('app')
.controller('AccountController',
function ($scope, $state) {
$scope.stateData = $state.current.data;
}
);
angular.module('app')
.controller(
'AccountController',
function ($scope, $state) {
$scope.stateData = $state.current.data;
}
);
angular
.module('app')
.controller(
'AccountController',
function ($scope, $state) {
$scope.stateData = $state.current.data;
}
);
Multi line comments should use the /* ... */
syntax; single line comments should use the // ...
syntax.
// single line comment
/*
* multi line comment.
* ooh, this is nice
*/
// instead of
/* what am i doing, why am i doing it? */
// hey,
// this is a multi line comment
// look at how silly i look
Functions should not, where possible, be bound to specifics. Instead, they should perform logic upon parameters passed to the function.
/**
* grabs the header, does some funky stuff with it, and returns the object
* @param {jQuery object} selector the selector upon which we're performing logic
* @return {jQuery object} the selector in its new state
*/
function doSomething (selector) {
selector = selector || $('#header');
...
}
// instead of
function doSomething () {
var selector = $('#header');
...
}
the 'use strict';
declaration must be used in the topmost level of function hierarchy. In many cases, this will be the first line of the IIFE body:
(function (win, doc) {
'use strict';
function doSomething () {
}
function doSomethingElse () {
}
}(window, document));
Should we prefix private variables with _
? It's a convention some people use (I have, myself, in the past), but I'm neither for or against it.
Douglass Crockford (the dude who developed JSON & jslint.com) recommends against it, since there's no real privacy in JS, and it could be misleading.
Companies like airbnb recommend using it.
Thoughts?
What do you think about this?
When using jQuery
selectors, you should assign them to variables:
function doSomething () {
var $header = $('#header'),
$nav = $('#main-nav'),
$content = $('#content'),
offset = $header.outerHeight(false) + $nav.outerHeight(false);
return $content.css({ marginTop : offset });
}
Doing this allows you to use a selector repeatedly without having to re-query the DOM; it also provides a meaningful naming convention in JavaScript should the selector be ambiguous (though it shouldn't be!)
Thinking about making our JavaScript more readable by splitting everything into modules. Check out this Gist for an example: https://gist.github.com/markgoodyear/688de5e5868f4e3e7461
What does everyone think?
You should not add whitespace between parens and arguments. You should space between comma-separated arguments.
// do this
function doSomething (arg, arg2) {
// stuff
}
doSomething(arg, arg2);
// not this
function doSomething ( arg, arg2 ) {
// stuff
}
doSomething( arg, arg2 );
// or this
function doSomething ( arg,arg2 ) {
// stuff
}
doSomething( arg,arg2 );
Object properties must be accessed using dot notation when the property being accessed is not dynamic:
var schema = {
revenue: {
indexes: [0.01, 1.00, 2.50, 5.00, 100.00],
colours: ['#bebebf', '#AADAE1', '#92E5E8', '#54D5D9', '#408F98'],
labels: ['0% of revenue', '<1% of revenue', '<2.5% of revenue', '<5% of revenue', '5%+ of revenue']
}
};
// like this
console.log(schema.revenue.indexes);
// instead of
console.log(schema[revenue][indexes]);
Bracket notation should only be used when accessing properties via a variable.
I do this.
When method chaining, you should break each method in the chain onto a new line, and align the periods:
function doSomething () {
var $header = $('#header');
$header.height(50)
.width(60)
.addClass('sexy')
.fadeOut();
return $header;
}
One:
var one = 'one';
var two = 'two';
var three = 'three';
Two:
var one = 'one',
two = 'two',
three = 'three';
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.