- Intro GETTING STARTED
- Approach
- Style REWORD TO MAKE MORE OBIVOUS
- Common Mistakes
- Tools
- Versions - WORK ENV Versions
- Blogs RESOURECS > RECOMMEND
- Github STARTER
- More Resources - BETTER NAMING
- Bootcamps
- Courses
- Mentee - MENTORS
- Contribute
- Future
- License
Welcome to all of those who are here reading this. This is the Green Pioneer Solutions style guide to code. We will be write about many bigger than just code and syntax. We will use this guide to help you in any way possible. For example were going to take a dive into other things that make us successful than just style like blogs, mentors, other style guides, mistakes and tools. Thats just to name a few.
Why: We are building this guide to help you figure
How: we plan to accomplish this by write how style our code and showing you lots
What: you will have a guide to come follow to help you along your journey as a developer
This guide is not a one size fits all. the goal
Maybe talk about my approach
Installs
Description of the JS
Description of the section
// Style
Description of the section
// Style
Description of the section
// Style
Description of the section
// Style
Description of the section
// Style
Description of the section
// Style
Description of the section
// Style
Declaring variables is a lot of fun. Sometimes, you may declare global variables even if you don't want to. In today's browsers, the global variables are stored in the window object. So, since there's a lot of stuff going on there, you may override default values.
Let's suppose you have an HTML file which contains a <script>
tag containing (or which loads a JavaScript file containing):
var foo = 42;
console.log(foo);
This will obviously output 42 in the console. But since the code is not executed in a function, the context will be the global one. So, the variables are attached to the window object. This means that window.foo is 42 as well.
This is dangerous since you can override existing global variables:
function print () {
// do something
}
print();
When executing window.print (or just print), it won't open the print popup since we have overriden the native print popup.
The solution is quite simple; we need a wrapping function that is called immediately, like below:
// Declare an anonymous function
(function () {
var foo = 42;
console.log(window.foo);
// → undefined
console.log(foo);
// → 42
})();
//^ and call it immediately
Alternatively, you could choose to send the window and other globals (e.g. document) as arguments to that function (this will probably improve the performance):
(function (global, doc) {
global.setTimeout(function () {
doc.body.innerHTML = "Hello!";
}, 1000);
})(window, document);
So, do use the wrapping function to prevent creating globals. Note that I'm not going to use the wrapping function in the code snippets below since we want to focus on the code itself.
💡 Tip: browserify is another way to prevent creating globals. It uses the require function the same way you do it in Node.js.
By the way, Node.js does wrap your files in functions automatically. They look like this:
(function (exports, require, module, __filename, __dirname) {
// ...
So if you thought the require function is a global one, well, it's not. It's nothing more than a function argument.
Did you know? Since the window object contains the global variables and since it is a global itself, the window references itself inside:
window.window.window
// => Window {...}
That's because the window object is a circular object. Here's how to create such an object:
// Create an object
var foo = {};
// Point a key value to the object itself
foo.bar = foo;
// The `foo` object just became a circular one:
foo.bar.bar.bar.bar
// → foo
Strictly use use strict
! This is nothing more than just adding string put in your code that adds more magic to your script.
// This is bad, since you do create a global without having anyone to tell you
(function () {
a = 42;
console.log(a);
// → 42
})();
console.log(a);
// → 42
Using use strict, you can get quite a few more errors:
(function () {
"use strict";
a = 42;
// Error: Uncaught ReferenceError: a is not defined
})();
You could be wondering why you can't put the use strict
outside of the wrapping function. Well, you can, but it will be applied globally. That's still not bad; but it will affect it if you have code which comes from other libraries, or if you bundle everything in one file.
This is short. If you compare a with b using == (like in other programming languages), in JavaScript you may find this works in a weird way: if you have a string and a number, they will be equal (==):
"42" == 42
// → true
For obvious reasons (e.g. validations), it's better to use strict equal (===):
"42" === 42
// → false
Depending on what you need to do, you can make your code shorter using logic operators.
Defaults
"" || "foo"
// → "foo"
undefined || 42
// → 42
// Note that if you want to handle 0 there, you need
// to check if a number was provided:
var a = 0;
a || 42
// → 42
// This is a ternary operator—works like an inline if-else statement
var b = typeof a === "number" ? a : 42;
// → 0
Instead of checking if something is truly using an if expression, you can simply do:
expr && doSomething();
// Instead of:
if (expr) {
doSomething();
}
That's even fancier if you need the result returned by doSomething():
function doSomething () {
return { foo: "bar" };
}
var expr = true;
var res = expr && doSomething();
res && console.log(res);
// → { foo: "bar" }
You may not agree with me here, but this is more ideal. If you don't want to uglify your code this way, this is what these JavaScript minifiers will actually do.
If you ask me, though the code is shorter, it is still human-readable.
There are several ways to convert these things depending on how you want to do it. The most common ways are:
// From anything to a number
var foo = "42";
var myNumber = +foo; // shortcut for Number(foo)
// → 42
// Tip: you can convert it directly into a negative number
var negativeFoo = -foo; // or -Number(foo)
// → -42
// From object to array
// Tip: `arguments` is an object and in general you want to use it as array
var args = { 0: "foo", 1: "bar", length: 2 };
Array.prototype.slice.call(args)
// → [ 'foo', 'bar' ]
// Anything to boolean
/// Non non p is a boolean p
var t = 1;
var f = 0;
!!t
// → true
!!f
// → false
/// And non-p is a boolean non-p
!t
// → false
!f
// → true
// Anything to string
var foo = 42;
"" + foo // shortcut for String(foo)
// → "42"
foo = { hello: "world" };
JSON.stringify(foo);
// → '{ "hello":"world" }'
JSON.stringify(foo, null, 4); // beautify the things
// →
// '{
// "hello": "world"
// }'
// Note you cannot JSON.stringify circular structures
JSON.stringify(window);
// ⚠ TypeError: JSON.stringify cannot serialize cyclic structures.
Using var
in general or let
when they should be accesible only in specific blocks (e.g. if
).
// One declaration
var foo = 1;
// Multiple declarations
var foo = 1
, bar = "Hello World"
, anotherOne = [{ foo: "bar" }]
;
if (...) {
let baz = 42;
/* do something with baz */
}
Using const
. The constant names are written with UPPERCASE letters. I also use const
when including libraries using require
and when they should not be changed. In this case, the names will not be with caps.
// Dependencies
const http = require("http")
, fs = require("fs")
, EventEmitter = require("events").EventEmitter
// Constants
const PI = Math.PI
, MY_CONSTANT = 42
;
I define globals when there is no commonjs environment (this is actually handled by dist-it
. When I manually define globals, I do that using window.MyGlobal
(on the client) and global.MyGlobal
(on the server).
For arrays, most of times, I use the forEach
function:
arr.forEach(c => {
// do something
});
However, using for
loops is fine too:
for (var i = 0; i < arr.length; ++i) {
for (var ii = 0; ii < arr[i].length; ++ii) {
...
}
...
}
For objects, I use the following style:
Object.keys(obj).forEach(k => {
var cValue = obj[k];
// do something
});
To simplify this, I created iterate-object
, which abstracts this functionality:
const iterateObject = require("iterate-object");
iterateObject(obj, (value, key) => {
// do something
});
See examples.
var foo = someObj
.method()
.method2()
.method3()
;
var a = cond ? v1 : v2;
var b = long_condition_here
? v1 : v2
;
var c = another_long_condition_here
? with_some_long_value
: or_another_some_long_value
;
I use backticks to create multiline strings:
var multiLineStr = `Lorem ipsum dolor sit amet, consectetur adipisicing elit
sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat
New line again...`;
Just don't, unless that's the scope of the library.
Using camel case notation for variables, in general. For constructors I capitalize the variable name (e.g. EventEmitter
).
// Node.JS require
const fs = require("fs")
, events = require("events")
, EventEmitter = events.EventEmitter
;
// Local variables
var x = 1
, twoWords = "Hello World"
;
// Functions
function fooBar () {...}
// Classes
class Person {
constructor (name, age) {
this.name = name;
this.age = age;
}
getName () {
return this.name;
}
}
// Object fields
var obj = {
full_name: "Johnny B."
, age: 20
};
obj.methodA = function () {...};
Open the curly brace at the end of the line. Always put the instructions between curly braces, even there is only one instruction.
if (expr) {
instr;
} else {
instr2;
instr3;
}
See examples.
// Arrays
var arr = [1, 2, 3, 4];
var lotOfElms = [
1, 2, 3, 4, 5, 6, 7
, 8, 9, 10, 11, 12, 13
, 14, 15, 16, 17, 18
];
var bigElms = [
"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod."
, "Tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim."
, "Veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea."
, "Commodo consequat. Duis aute irure dolor in reprehenderit in voluptate"
];
// Objects
var obj = { a: 1 };
var obj1 = {
full_name: "Johnny B."
, age: 20
};
Double quotes, with some exceptions when single quotes are used.
var foo = "\"Hello\", he said.";
var jQuerySelector = "div.myClass[data-foo='bar']";
Use slashes for both single line and multi line comments. Try to write comments that explain higher level mechanisms or clarify difficult segments of your code. Don't use comments to restate trivial things.
Right:
// 'ID_SOMETHING=VALUE' -> ['ID_SOMETHING=VALUE', 'SOMETHING', 'VALUE']
var matches = item.match(/ID_([^\n]+)=([^\n]+)/));
// This function has a nasty side effect where a failure to increment a
// redis counter used for statistics will cause an exception. This needs
// to be fixed in a later iteration.
function loadUser(id, cb) {
// ...
}
var isSessionValid = (session.expires < Date.now());
if (isSessionValid) {
// ...
}
Wrong:
// Execute a regex
var matches = item.match(/ID_([^\n]+)=([^\n]+)/);
// Usage: loadUser(5, function() { ... })
function loadUser(id, cb) {
// ...
}
// Check if the session is valid
var isSessionValid = (session.expires < Date.now());
// If the session is valid
if (isSessionValid) {
// ...
}
Put relevant comments. The comments start with uppercase letter.
// Dependencies
const lib1 = require("lib1")
, lib2 = require("lib2")
;
// Constants
const FOURTY_TWO = 42;
Single line comments start with //
. For multi-line commands, you use /* ... */
/* This is a single line comment */
// or
// This is a single line comment
/*
And this is
a multi-line
comment
*/
//or
// And this is
// a multi-line
// comment
Use if (expression) { ... } else { ... }
to do something if expression is true or not.
let foo = 42;
if (foo > 40) {
// do something
} else {
// do something else
}
Description of the section
let planet = 'Earth';
switch (planet) {
case "Mercury":
case "Venus":
console.log("Too hot here.");
case 'Earth' :
console.log("Welcome home!");
break;
case 'Mars' :
console.log("Welcome to the other home!");
break;
case "Jupiter":
case "Saturn":
case "Uranus":
case "Neptune":
case "Pluto":
console.log("You may get gold here.");
break;
default:
console.log("Seems you found another planet.");
break;
}
The following ones, are primitives:
- Booleans: false, true
- Numbers: 42, 3.14, 0b11010, 0x16, NaN (check out The magic of numbers)
- Strings: 'Earth', "Mars"
- Special values: undefined, null
Want to parse them ? try auto parse
The common way to declare objects is by using the curly braces:
let myObj = { world: "Earth" };
Attention: Objects are compared by reference. That being said, we have this:
let firstObj = {};
let secondObj = {};
// Check if they are equal
firstObj === secondObj
→ false
// Comparing an object with itself...
firstObj === firstObj
→ true
// Let's point the secondObj to firstObj
secondObj = firstObj
// Now they are equal
firstObj === secondObj
→ true
Attention: you have no guarantee that adding the object keys in a specific order will get them in the same order. Object keys are not ordered, even in general JavaScript interpreters which will iterate them in the order of adding them in the object (again, do not rely on this feature).
In addition to objects, the array data is ordered by indexes. Arrays are actually objects, having the indexes (numbers from 0 to legnth - 1) as keys.
let fruits = ["apples", "pears", "oranges"];
fruits[1]
→ "pears"
> let fruits = ["Apple"]
// Add to the end of the array
> fruits.push("Pear")
2 // < The new length of the array
[ 'Apple', 'Pear' ]
// ^ This was just added
// Add to the start of the array
> fruits.unshift("Orange")
3 // < The new length of the array
[ 'Orange', 'Apple', 'Pear' ]
// ^ This was just added
// Access the element at index 1 (the second element)
> fruits[1]
'Apple'
// How many items do we have?
> fruits.length
3
// Turn the Apple into Lemon
> fruits[1] = "Lemon"
'Lemon'
[ 'Orange', 'Lemon', 'Pear' ]
// ^ This was before an Apple
// Insert at index 1 a new element
> fruits.splice(1, 0, "Grapes")
[] // < Splice is supposed to delete things (see below)
// In this case we're deleting 0 elements and
// inserting one.
[ 'Orange', 'Grapes', 'Lemon', 'Pear' ]
// ^ This was added.
// Get the Lemon's index
> fruits.indexOf("Lemon")
2
// Delete the Lemon
> fruits.splice(2, 1)
[ 'Lemon' ]
[ 'Orange', 'Grapes', 'Pear' ]
// ^ Lemon is gone
// Remove the last element
> fruits.pop()
'Pear'
[ 'Orange', 'Grapes' ]
// ^ Pear is gone
// Remove the first element
> fruits.shift()
'Orange'
[ 'Grapes' ]
// ^ Orange is gone
There are few ways to loop trough an array.
// Using for-loop
var arr = [42, 7, -1]
for (var index = 0; index < arr.length; ++index) {
var current = arr[index];
/* Do something with `current` */
}
// Others prefer defining an additional `length` variable:
for (var index = 0, length = arr.length; index < length; ++index) {
var current = arr[index];
/* ... */
}
// Another way i using `forEach`:
arr.forEach((current, index, inputArray) => {
/* Do something with `current` */
});
// Or using the for ... of:
for (let current of arr) {
/* current will be the current element */
}
There are a couple of ways to define functions in JavaScript. The common uses are:
function sum (a, b) {
return a + b;
}
var sum = function (a, b) {
return a + b;
}
// Using the ES6 arrow functions
let sum = (a, b) => a + b;
Then you can call the function like:
let result = sum(40, 2);
// => 42
Description of the section
SUGGEST DESIGN PATTERNS
There are a couple of ways you can obtain a class-like functionality in JavaScript.
Factory functions Creating an object and returning it.
function Person (name) {
var self = {};
// Public field
self.name = name;
// Public method
self.getName = function () {
// `this` is the `self`
return this.name;
};
return self;
}
var p = Person("Alice");
console.log(p.getName());
// => "Alice"
Using prototype
s
By adding a method in the prototype object of a function, you're adding that method as a public method to all the instances of that class.
function Person (name) {
this.name = name;
}
Person.prototype.getName = function () {
// `this` is the `self`
return this.name;
};
var p = new Person("Bob");
console.log(p.getName());
// => "Bob"
Using ES6 classes
class Person {
constructor (name) {
this.name = name;
}
getName () {
return this.name;
}
}
var p = new Person("Carol");
console.log(p.getName());
// => "Bob"
It's also very easy to inherit classes in ES6:
class Musician extends Person {
constructor (name, instrument) {
// Call the base class
super(name);
this.instrument = instrument;
}
play () {
console.log(`${this.getName()} is playing ${this.instrument}`);
}
}
var me = new Musician("Johnny B.", "piano");
// Get the name of the musician, who is also a person
console.log(me.getName());
// => "Johnny B."
me.play();
// => "Johnny B. is playing piano."
Sometimes you have to wait a little bit for things to be done: such as when making a cake, you have to work on it and you have to wait a while for it to be ready. Most familiar things in our lives are asynchronous.
Sync Usually, synchronous operations send the response directly, using the return keyword:
// Synchronous sum function sum (a, b) { return a + b; } var result = sum(40, 2); // => 42 Async To have an async function, you need a source of async stuff. In this example, we will use the setTimeout function. It accepts a function as first argument (which is called callback function) and a number as second argument—representing the time delay after the function is called:
function asyncSum (a, b, cb) { setTimeout(function () { cb(a + b); // -----------+ This is the place }, 1000); // | where we call then } // V callback function asyncSum(40, 2, function (result) { console.log(result); // => 42 });
// Style
callbacks are functions which are sent as an argument to another function and are invoked when something happens.
function Cake() { /* Just a dummy class-like constructor for now */ }
// We won't make a ckae if we're busy
var busy = false;
function makeCake ( callback) {
// If we're busy making a cake, send back an error
if (busy) {
return callback(new Error("Already busy with creating a cake. Please wait a bit and try again later."));
}
// Well, if we weren't busy before, we are now
busy = true;
// Wait one second
setTimeout(function () { // <- This is a callback function too. It is called after one second.
// After one second we call the callback function
callback(null, new Cake());
// After sending the cake, we're not busy anymore
busy = false;
}, 1000);
}
makeCake(function (err, cake) {
if (err) { console.error(err); }
console.log("Made a cake.");
// => "Made a cake."
});
// This will end with an error because we're busy already
makeCake(function (err, cake) {
if (err) { console.error(err); }
// !=> "Already busy with creating a cake. Please wait a bit and try again later."
console.log("Made a cake.");
});
// Wait 2 seconds
setTimeout(function () {
// This will work again
makeCake(function (err, cake) {
if (err) { console.error(err); }
console.log("Made a cake.");
// => "Made a cake."
});
}, 2000);
There is a thing called Promise. Let's see an example:
function sum (a, b) {
return Promise(function (resolve, reject) {
// Let's wait a second and only then send the response
setTimeout(function () {
if (typeof a !== "number" || typeof b !== "number") {
return reject(new TypeError("Please provide two numbers to sum."));
}
resolve(a + b);
}, 1000);
});
}
var myPromise = sum(40, 2);
myPromsise.then(function (result) {
// After one second we have the response here
console.log("> Summed 40 + 2: ", result);
// Let's pass some invalid data and return another promise
return sum(null, "foo");
}).then(function () {
// This won't be called because we have an error
}).catch(function (err) {
// Instead, this `catch` handler is called: (after another second)
console.error(err);
// => Please provide two numbers to sum.
});
A promise can be in one of these three states:
- pending: the operation is pending
- fulfilled: the operation was finished
- rejected: an error appeared, so the promise is rejected
StackOverflow Documention has a good section about promises here.
To create an error, you have to use the Error constructor:
let myError = new Error("Something went really wrong.");
// You can even append custom data here
myError.code = "MY_FANCY_ERROR_CODE";
To throw an error, you have to use the throw statement:
throw new Error("Something bad happened."); There are few types of errors. For example, if you validate the arguments passed to a function, use TypeError:
function sayHello(message) {
if (typeof message !== "string") {
throw new TypeError("The message should be a string.");
}
console.log(message);
}
When you have a callback interface it's friendlier to send the errors using the callback functions.
In the Promises (even on the interface) it's friendlier to send the errors using the reject functions.
In general, it is a good practice to validate the data you're passing to function (especially when they are coming from the user input). This way you can avoid TypeErrors to be thrown.
If there's a function which throws an error by design, you can catch it using try - catch:
function assert (truly) {
if (!truly) {
throw new Error("Not true.");
}
}
try {
// This will *not* throw an error
assert(42 === 42);
// This will throw an error, so that will go in the catch
assert(42 === -1);
// Everything put after the place where the error was thrown
// is not executed
} catch (e) {
console.error(e);
// => Not true.
}
Note if you have an async function (either callback-based or which returns a promise), you'll do something like this:
// Callback
fetchDataFromServer(function (err, data) {
if (err) {
/* do something if you have an error */
} else {
/* Do something with `data` */
}
});
// Promise
fetchDataFromServer().then(function (data) {
/* Do something with `data` */
}).catch(function (err) {
/* do something if you have an error */
});
Description of the section
// Style
You can increment a variable name x
using ++x
or x++
. Similarly, you can decrement it by --x
or x--
.
The difference is that ++x
(--x)
returns the incremented (decremented) value, while x++
(x--)
returns the previous value of x.
// Let's declare x
let x = 42;
// Store in y, the result of ++x
let y = ++x;
// Let's see the result
console.log(`x is ${x} and y is ${y}`);
→ 'x is 43 and y is 43'
// Now, store in y the result of x++. Note, x is now 43.
y = x++;
// Let's see again
console.log(`x is ${x} and y is ${y}`);
→ 'x is 44 and y is 43'
// So, `y` is 43, because `x++` returned the pre-incremented value (which was 43)
This will print all the integers from 1 to 42.
for (var i = 1; i <= 42; ++i) {
console.log(i);
}
Using for ... in ... can be used to iterate object keys:
var name = {
first: "Johnny",
last: "B."
};
for (var key in name) {
if (name.hasOwnProperty(key)) {
console.log(key, name[key]);
// "first", "Johnny"
// "last", "B."
}
}
In ES6 there is a for ... of ... as well. It's pretty neat since it iterates any iterable objects (arrays, strings etc).
let numbers = [-1, 7, 42, 64];
for (let num of numbers) {
console.log(num);
}
// -1
// 7
// 42
// 64
while
var i = 1;
while (i <= 42) {
console.log(i);
++i;
}
do - while
var i = 0;
do {
++i;
console.log(i);
} while (i < 42);
Regular expressions are a lot of fun. They are delimited by slashes:
/^[0-9]+$/gm.test("a")
// => false
/^[0-9]+$/gm.test("42")
// => true
A regular expression has a pattern and flags. The pattern in this example is ^[0-9]+$—meaning if the input is one or more digits (from 0 to 9), we validate it—while the flags are g (global) and m (multiline).
regex101.com is a good resource for visualizing and sharing regular expressions with others:
javascript cheat sheet
Regular expressions can be used to match things in strings, such as numbers:
// Get all the numbers from this input (note you'll get an array of strings)
> "Alice was born in 1974, so she's 42 years old in 2016.".match(/[0-9]+/g)
[ '1974', '42', '2016' ]
// Want to get numbers? Map them using the `Number` function
> "Alice was born in 1974, so she's 42 years old in 2016.".match(/[0-9]+/g).map(Number)
[ 1974, 42, 2016 ]
// BE CAREFUL that if there's no match `match` will return `null`
> "Bob is seven years old.".match(/[0-9]+/g)
null
Also, they can be used to replace parts of the strings:
// Mask all the digits of a credit card number, but the last 4
"1234234534564567".replace(/\d(?=\d{4})/g, "*"); '************4567'
// Style
// Get the PI number
> Math.PI
3.141592653589793
// Get the E number
> Math.E
2.718281828459045
// Maximum between two numbers
> Math.max(7, 42)
42
// Minimum between numbers (arguments)
> Math.min(7, 42, 255, 264)
7
// Power
> Math.pow(2, 4)
16
// Random number between 0 (inclusive) and 1 (exclusive)
> Math.random()
0.2114640628617317
// Round
> Math.round(41.8)
42
There are trigonometric functions as well: sin, cos, tan, atan etc. Note these require radians. One radian is 180 degrees.
Use the Date constructor to create date objects.
var now = new Date();
now.getFullYear();
// => 2016
If you want to have fancy stuff like formatting dates, etc., use libraries like moment
.
Variables, properties and function names should use lowerCamelCase. They should also be descriptive. Single character variables and uncommon abbreviations should generally be avoided.
Right:
var adminUser = db.query('SELECT * FROM users ...');
Wrong:
var admin_user = db.query('SELECT * FROM users ...');
Class names should be capitalized using UpperCamelCase.
Right:
function BankAccount() {
}
Wrong:
function bank_Account() {
}
Constants should be declared as regular variables or static class properties, using all uppercase letters.
Right:
var SECOND = 1 * 1000;
function File() {
}
File.FULL_PERMISSIONS = 0777;
Wrong:
const SECOND = 1 * 1000;
function File() {
}
File.fullPermissions = 0777;
Keep your functions short. A good function fits on a slide that the people in the last row of a big room can comfortably read. So don't count on them having perfect vision and limit yourself to ~15 lines of code per function.
To avoid deep nesting of if-statements, always return a function's value as early as possible.
Right:
function isPercentage(val) {
if (val < 0) {
return false;
}
if (val > 100) {
return false;
}
return true;
}
Wrong:
function isPercentage(val) {
if (val >= 0) {
if (val < 100) {
return true;
} else {
return false;
}
} else {
return false;
}
}
Or for this particular example it may also be fine to shorten things even further:
function isPercentage(val) {
var isInRange = (val >= 0 && val <= 100);
return isInRange;
}
Feel free to give your closures a name. It shows that you care about them, and will produce better stack traces, heap and cpu profiles.
Right:
req.on('end', function onEnd() {
console.log('winning');
});
Wrong:
req.on('end', function() {
console.log('losing');
});
Use closures, but don't nest them. Otherwise your code will become a mess.
Right:
setTimeout(function() {
client.connect(afterConnect);
}, 1000);
function afterConnect() {
console.log('winning');
}
Wrong:
setTimeout(function() {
client.connect(function() {
console.log('losing');
});
}, 1000);
One method per line should be used if you want to chain methods.
You should also indent these methods so it's easier to tell they are part of the same chain.
Right:
User
.findOne({ name: 'foo' })
.populate('bar')
.exec(function(err, user) {
return true;
});
Wrong:
User
.findOne({ name: 'foo' })
.populate('bar')
.exec(function(err, user) {
return true;
});
User.findOne({ name: 'foo' })
.populate('bar')
.exec(function(err, user) {
return true;
});
User.findOne({ name: 'foo' }).populate('bar')
.exec(function(err, user) {
return true;
});
User.findOne({ name: 'foo' }).populate('bar')
.exec(function(err, user) {
return true;
});
Crazy shit that you will probably never need. Stay away from it.
Always put requires at top of file to clearly illustrate a file's dependencies. Besides giving an overview for others at a quick glance of dependencies and possible memory impact, it allows one to determine if they need a package.json file should they choose to use the file elsewhere.
Do not use setters, they cause more problems for people who try to use your software than they can solve.
Feel free to use getters that are free from side effects, like providing a length property for a collection class.
Do not extend the prototype of native JavaScript objects. Your future self will be forever grateful.
Right:
var a = [];
if (!a.length) {
console.log('winning');
}
Wrong:
Array.prototype.empty = function() {
return !this.length;
}
var a = [];
if (a.empty()) {
console.log('losing');
}
-
Use 2 spaces for indentation.
function hello (name) { console.log('hi', name) }
-
Use single quotes for strings except to avoid escaping.
console.log('hello there') $("<div class='box'>")
-
No unused variables.
function myFunction () { var result = something() // ✗ avoid }
-
Add a space after keywords.
if (condition) { ... } // ✓ ok if(condition) { ... } // ✗ avoid
-
Add a space before a function declaration's parentheses.
function name (arg) { ... } // ✓ ok function name(arg) { ... } // ✗ avoid run(function () { ... }) // ✓ ok run(function() { ... }) // ✗ avoid
-
Always use
===
instead of==
.
Exception:obj == null
is allowed to check fornull || undefined
.if (name === 'John') // ✓ ok if (name == 'John') // ✗ avoid
if (name !== 'John') // ✓ ok if (name != 'John') // ✗ avoid
-
Infix operators must be spaced.
// ✓ ok var x = 2 var message = 'hello, ' + name + '!'
// ✗ avoid var x=2 var message = 'hello, '+name+'!'
-
Commas should have a space after them.
// ✓ ok var list = [1, 2, 3, 4] function greet (name, options) { ... }
// ✗ avoid var list = [1,2,3,4] function greet (name,options) { ... }
-
Keep else statements on the same line as their curly braces.
// ✓ ok if (condition) { // ... } else { // ... }
// ✗ avoid if (condition) { // ... } else { // ... }
-
For multi-line if statements, use curly braces.
// ✓ ok if (options.quiet !== true) console.log('done')
// ✓ ok if (options.quiet !== true) { console.log('done') }
// ✗ avoid if (options.quiet !== true) console.log('done')
-
Always handle the
err
function parameter.// ✓ ok run(function (err) { if (err) throw err window.alert('done') })
// ✗ avoid run(function (err) { window.alert('done') })
-
Always prefix browser globals with
window.
.
Exceptions are:document
,console
andnavigator
.window.alert('hi') // ✓ ok
-
Multiple blank lines not allowed.
// ✓ ok var value = 'hello world' console.log(value)
// ✗ avoid var value = 'hello world' console.log(value)
-
For the ternary operator in a multi-line setting, place
?
and:
on their own lines.// ✓ ok var location = env.development ? 'localhost' : 'www.api.com' // ✓ ok var location = env.development ? 'localhost' : 'www.api.com' // ✗ avoid var location = env.development ? 'localhost' : 'www.api.com'
-
For var declarations, write each declaration in its own statement.
// ✓ ok var silent = true var verbose = true // ✗ avoid var silent = true, verbose = true // ✗ avoid var silent = true, verbose = true
-
Wrap conditional assignments with additional parentheses. This makes it clear that the expression is intentionally an assignment (
=
) rather than a typo for equality (===
).// ✓ ok while ((m = text.match(expr))) { // ... } // ✗ avoid while (m = text.match(expr)) { // ... }
-
window.alert('hi') // ✓ ok window.alert('hi'); // ✗ avoid
-
Never start a line with
(
,[
, or`
. This is the only gotcha with omitting semicolons, and standard protects you from this potential issue.// ✓ ok ;(function () { window.alert('ok') }()) // ✗ avoid (function () { window.alert('ok') }())
// ✓ ok ;[1, 2, 3].forEach(bar) // ✗ avoid [1, 2, 3].forEach(bar)
// ✓ ok ;`hello`.indexOf('o') // ✗ avoid `hello`.indexOf('o')
Note: If you're often writing code like this, you may be trying to be too clever.
Clever short-hands are discouraged, in favor of clear and readable expressions, whenever possible.
Instead of this:
;[1, 2, 3].forEach(bar)
This is much preferred:
var nums = [1, 2, 3] nums.forEach(bar)
// Style
Description of the section
// Style
- Headers
- Emphasis
- Lists
- Links - these
- Images
- Code
- Tables
- Block Quotes
- Inline HTML
- Horizontal Rules
- Line Breaks
- Video Embedding
- Not using development tools
- Blocking the event loop
- Executing a callback multiple times
- The Christmas tree of callbacks (Callback Hell)
- Creating big monolithic applications
- Poor logging
- No tests
- Not using static analysis tools
- Zero monitoring or profiling
- Debugging with console.log
Framework/Library/Program | Version |
---|---|
Angular | 1.X |
JQuery | 3.X |
NodeJs | 6.X |
Centos | 7 |
NodeJs | 6.X |
This section is devoted to blogs that just talk about and have alot of great content. Please reach out and contact me if you think i should have yours in here.
- simpleprogrammer
- https://blog.risingstack.com/
- https://www.codementor.io
- https://toddmotto.com/
- https://scotch.io/
- https://davidwalsh.name/
- http://dailyjs.com/
- https://www.sitepoint.com/javascript/
- https://www.javascript.com/
- http://blog.teamtreehouse.com/
- http://www.nearform.com/nodecrunch/
coming soon
coming soon
coming soon
coming soon
coming soon
coming soon
coming soon
coming soon
###run-auto
npm install run-auto --save
var auto = require('run-auto')
auto({
getData: function (callback) {
console.log('in getData')
// async code to get some data
callback(null, 'data', 'converted to array')
},
makeFolder: function (callback) {
console.log('in makeFolder')
// async code to create a directory to store a file in
// this is run at the same time as getting the data
callback(null, 'folder')
},
writeFile: ['getData', 'makeFolder', function (results, callback) {
console.log('in writeFile', JSON.stringify(results))
// once there is some data and the directory exists,
// write the data to a file in the directory
callback(null, 'filename')
}],
emailLink: ['writeFile', function (results, callback) {
console.log('in emailLink', JSON.stringify(results))
// once the file is written let's email a link to it...
// results.writeFile contains the filename returned by writeFile.
callback(null, { file: results.writeFile, email: '[email protected]' })
}]
}, function(err, results) {
console.log('err = ', err)
console.log('results = ', results)
})
// With Multiple Mongo Calls
auto({
blogs: function (cb) {
blogs
.find()
.populate('user')
.exec(cb)
},
users: function (cb) {
users
.find()
.populate('user')
.exec(cb)
},
tester: function (cb) {
tester
.find()
.populate('user')
.exec(cb)
},
todos: function (cb) {
todos
.find()
.populate('user')
.exec(cb)
}
}, function (err, results) {
if (err) return next(err)
return res.status(200).send(results)
})
- Download and Install mongodb - Checkout their manual if you're just starting.
$ npm install mongoose-validator --save
var mongoose = require('mongoose');
var validate = require('mongoose-validator');
var nameValidator = [
validate({
validator: 'isLength',
arguments: [3, 50],
message: 'Name should be between {ARGS[0]} and {ARGS[1]} characters'
}),
validate({
validator: 'isAlphanumeric',
passIfEmpty: true,
message: 'Name should contain alpha-numeric characters only'
})
];
var Schema = new mongoose.Schema({
name: {type: String, required: true, validate: nameValidator}
});
npm install express-validator --save
var util = require('util'),
express = require('express'),
expressValidator = require('express-validator'),
app = express.createServer();
app.use(express.bodyParser());
app.use(expressValidator([options])); // this line must be immediately after express.bodyParser()!
app.post('/:urlparam', function(req, res) {
// VALIDATION
req.assert('postparam', 'Invalid postparam').notEmpty().isInt();
req.assert('urlparam', 'Invalid urlparam').isAlpha();
req.assert('getparam', 'Invalid getparam').isInt();
// SANITIZATION
// as with validation these will only validate the relevent param in all areas
req.sanitize('postparam').toBoolean();
var errors = req.validationErrors();
if (errors) {
res.send('There have been validation errors: ' + util.inspect(errors), 400);
return;
}
res.json({
urlparam: req.params.urlparam,
getparam: req.params.getparam,
postparam: req.params.postparam
});
});
app.listen(8888);
npm install validator --save
var validator = require('validator');
validator.isEmail('[email protected]'); //=> true