All code in any code-base should look like a single person typed it, no matter how many people contributed.
<!-- HTML 5 -->>
<!DOCTYPE html>
<li>Some text here.
<li>Some new text here.
<li>You get the idea.
//Bad code
<span class="heading"><strong>Welcome Back</span></strong>
<br><br>
It has been a while. What have you been up to lately?
<br><br>
//Good Code
<h1>Welcome Back</h1>
<p>It has been a while. What have you been up to lately?</p>
5. Use alt for img tags
6. No inline - CSS or JavaScript
7. Learn the html tags
8. Understand and use CSS Resets
9. Do not use IDs in CSS selectors
10. Use specific classes when necessary
11. Use shorthand properties and values
img {
margin: 5px 10px;
}
button {
padding-left: 20px;
}
a,
.btn {
background: #aaa;
color: #f60;
font-size: 18px;
padding: 6px;
}
.Red_Box { ... } //NO
.alert-message { ... } //YES
14. Modularize styles for re-use
15. Avoid using tables!!
16. Browser support
17. Provide fallbacks for media
<audio controls>
<source src=sound.ogg type=audio/ogg>
<source src=sound.mp3 type=audio/mp3>
<!-- fallback content: -->
<a href=sound.ogg>Ogg</a>
<a href=sound.mp3>MP3</a>
</audio>
<video controls>
<source src=video.webm type=video/webm>
<source src=video.mp4 type=video/mp4>
<!-- fallback content: -->
<iframe width="480" height="360" src="#" frameborder="0" allowfullscreen>/<iframe>
</video>
18. Forms
if(condition) doSomething();
while(condition) iterating++;
for(var i=0;i<100;i++) someIterativeFn();
// Use whitespace to promote readability if ( condition ) { // statements } while ( condition ) { // statements } for ( var i = 0; i < 100; i++ ) { // statements }
var prop; for ( prop in object ) { // statements } if ( true ) { // statements } else { // statements }
// Variables var foo = "bar", num = 1, undef; // Literal notations: var array = [], object = {};
// Using only one `var` per scope (function) promotes readability // and keeps your declaration list free of clutter (also saves a few keystrokes)
// Bad var foo = ""; var bar = ""; var qux; // Good var foo = "", bar = "", quux;
One Scope -> One var
// Bad
function foo() {
// some statements here
var bar = "",
qux;
}
// Good
function foo() {
var bar = "",
qux;
// all statements after the variables declarations.
}
// Named Function Declaration function foo( arg1, argN ) { } // Usage foo( arg1, argN ); // Function Expression var square = function( number ) { // Return something valuable and relevant return number * number; };
// Constructor Declaration function FooBar( options ) { this.options = options; } // Usage var fooBar = new FooBar({ a: "alpha" }); fooBar.options;
// Functions with callbacks foo(function() { // Note there is no extra space between the first paren // of the executing function call and the word "function" }); // Function accepting an array, no space foo([ "alpha", "beta" ]);
// Function accepting an object, no space foo({ a: "alpha", b: "beta" }); // Single argument string literal, no space foo("bar"); // Inner grouping parens, no space if ( !("foo" in obj) ) { }
if (condition) { // statements } while (condition) { // statements } for (var i = 0; i < 100; i++) { // statements }
if (true) { // statements } else { // statements }
String: typeof variable === "string"
Number: typeof variable === "number"
Boolean: typeof variable === "boolean"
Object: typeof variable === "object"
Array: Array.isArray( arrayLikeObject ) (wherever possible)
// `foo` has been declared with the value `0` and its type is `number` var foo = 0;
// typeof foo; ?
foo = document.getElementById("foo-input").value;
// typeof foo; ?
if ( foo === 1 ) { importantTask(); }
// You can preempt issues by using smart coercion with unary + or - operators:
foo = +document.getElementById("foo-input").value;
// ^ unary + operator will convert its right side operand to a number
// typeof foo; ??
if ( foo === 1 ) {
importantTask();
}
var number = 1,
string = "1",
bool = false;
number; //answer?
number + "";
string;
+string;
+string++;
string;
bool;
+bool;
bool + "";
"1", "1", 1, 1, 2, false, 0, "false"
var number = 1, string = "1", bool = true; string === number; string === number + "";
+string === number; bool === number; +bool === number; bool === string; bool === !!string;
// When only evaluating that an array has length, // instead of this: if ( array.length > 0 ) ... // ...evaluate truthiness, like this: if ( array.length ) ...
// When only evaluating that an array is empty, // instead of this: if ( array.length === 0 ) ... // ...evaluate truthiness, like this: if ( !array.length ) ...
// When only evaluating that a string is not empty,
// instead of this: if ( string !== "" ) ...
// ...evaluate truthiness, like this: if ( string ) ...
// When only evaluating that a string _is_ empty, // instead of this: if ( string === "" ) ...
// ...evaluate falsy-ness, like this: if ( !string ) ...
// When only evaluating that a reference is true, // instead of this: if ( foo === true ) ...
// ...evaluate like you mean it, take advantage of built in capabilities: if ( foo ) ... // When evaluating that a reference is false, // instead of this: if ( foo === false ) ...
// ...use negation to coerce a true evaluation if ( !foo ) ...
// ...Be careful, this will also match: 0, "", null, undefined, NaN
// If you _MUST_ test for a boolean false, then use if ( foo === false ) ...
// When only evaluating a ref that might be null or undefined, but NOT false, "" or 0, // instead of this: if ( foo === null || foo === undefined ) ...
// ...take advantage of == type coercion, like this: if ( foo == null ) ...
// Remember, using == will match a `null` to BOTH `null` and `undefined` // but not `false`, "" or 0 null == undefined
// Example of code with poor names
function q(s) {
return document.querySelectorAll(s);
}
var i,a=[],els=q("#foo");
for(i=0;i<els.length;i++){a.push(els[i]);}
// Same code with improved names
function query( selector ) {
return document.querySelectorAll( selector );
}
var idx = 0,
elements = [],
matches = query("#foo"),
length = matches.length;
for ( ; idx < length; idx++ ) {
elements.push( matches[ idx ] );
}
// Naming strings `dog` is a string // Naming arrays `dogs` is an array of `dog` strings
// Naming functions, objects, instances, etc camelCase; function and var declarations // Naming pseudo-classes, constructors, prototypes, etc. PascalCase; constructor function // Naming regular expressions rDesc = //;
functionNamesLikeThis;
variableNamesLikeThis;
ConstructorNamesLikeThis;
EnumNamesLikeThis;
methodNamesLikeThis;
SYMBOLIC_CONSTANTS_LIKE_THIS;
function Device( opts ) { this.value = null;
// open an async stream, // this will be called continuously stream.read( opts.path, function( data ) {
// Update this instance's current value // with the most recent value from the // data stream this.value = data; }.bind(this) );
// Throttle the frequency of events emitted from // this Device instance setInterval(function() { // Emit a throttled event this.emit("event"); }.bind(this), opts.freq || 100 ); }
// underscore, _.bind() function Device( opts ) { this.value = null; stream.read( opts.path, _.bind(function( data ) { this.value = data; }, this) ); setInterval(_.bind(function() { this.emit("event");
}, this), opts.freq || 100 ); }
function Device( opts ) { var self = this; this.value = null; stream.read( opts.path, function( data ) { self.value = data; }); setInterval(function() { self.emit("event");
}, opts.freq || 100 ); }
var obj; obj = { f: "foo", b: "bar", q: "qux" }; Object.keys( obj ).forEach(function( key ) { // |this| now refers to `obj` console.log( this[ key ] ); }, obj ); // <-- the last arg is `thisArg` // Prints...
// "foo" // "bar" // "qux"
// Bad: function returnLate( foo ) { var ret; if ( foo ) { ret = "foo"; } else { ret = "quux"; } return ret; }
// Good: function returnEarly( foo ) { if ( foo ) { return "foo"; } return "quux"; }
var foo = function() { return true; }; // semicolon here.
function foo() { return true; } // no semicolon here.
if (x) {
function foo() {}
}
if (x) {
var foo = function() {};
}
//Use
Foo.prototype.dispose = function() { this.property_ = null; };
//Instead of: Foo.prototype.dispose = function() { delete this.property_; };
{ "name": "Alice", "id": 31502, "email": "looking_glass@example.com" }
//NO TO THIS PLEASE
var userInfo = eval(feed); var email = userInfo['email'];
// USE ALTERNATIVES INSTEAD
var userInfo = JSON.parse(feed); var email = userInfo['email'];
//NO TO THIS
var myString = 'A rather long string of English text, an error message \ actually that just keeps going and going -- an error \ message to make the Energizer bunny blush (right through \ those Schwarzenegger shades)! Where was I? Oh yes, \ you\'ve got an error and all the extraneous whitespace is\ just gravy. Have a nice day.';
//USE CONCATENATION INSTEAD
var myString = 'A rather long string of English text, an error message ' + 'actually that just keeps going and going -- an error ' + 'message to make the Energizer bunny blush (right through ' + 'those Schwarzenegger shades)! Where was I? Oh yes, ' + 'you\'ve got an error and all the extraneous whitespace is ' + 'just gravy. Have a nice day.';
//BAD
// Length is 3. var a1 = new Array(x1, x2, x3);
// Length is 2. var a2 = new Array(x1, x2);
//GOOD
var a = [x1, x2, x3];
var a2 = [x1, x2];
//BAD
var o = new Object(); var o2 = new Object(); o2.a = 0; o2.b = 1; o2.c = 2;
o2['strange key'] = 3;
//GOOD
var o = {}; var o2 = { a: 0, b: 1, c: 2, 'strange key': 3 };
Object.prototype
Array.prototype
Function.prototype
Boolean('0') == true '0' != true 0 != null 0 == [] 0 == false
Boolean(null) == false null != true null != false
Boolean(undefined) == false undefined != true undefined != false
Boolean([]) == true [] != true [] == false Boolean({}) == true {} != true {} != false
/** @param {*=} opt_win */
function foo(opt_win) {
var win = opt_win || window;
// ...
}
var kid = node && node.kids && node.kids[index];
if (kid) {
foo(kid);
}
Don't have more than 4 filters while checking
var paragraphs = document.getElementsByTagName('p');
for (var i = 0; i < paragraphs.length; i++) {
doSomething(paragraphs[i]);
}
var paragraphs = document.getElementsByTagName('p');
for (var i = 0, paragraph; paragraph = paragraphs[i]; i++) {
doSomething(paragraph);
}
/**
* Illustrates line wrapping for long param/return descriptions.
* @param {string} foo This is a param with a description too long to fit in
* one line.
* @return {number} This returns something that has a description too long to
* fit in one line.
*/
project.MyClass.prototype.method = function(foo) {
return 5;
};