-
-
Notifications
You must be signed in to change notification settings - Fork 35.4k
Mr.doob's Code Style™
- Code should be in UTF-8.
- a new line should be LF.
- Indentation should be tabs.
- No extra spaces at the end of lines (set up your text editor, so that it removes extra spaces when saving).
Naming should be as descriptive as possible. The only exception is the indexing variable in an loop. That can be shortened to a single letter starting from i.
- variableNamesLikeThis
- functionNamesLikeThis
- ClassNamesLikeThis
- methodNamesLikeThis
- ConstantsLikeThis Private properties and methods of objects begin with an underscore _.
- Object should always be created by
{}
and notnew Object()
. - When creating an empty Object, use
{}
without spaces. - When creating an Object with keys,
- There should be a single space after the opening bracket.
- There should be a single space before the closing bracket.
- Keys should be written without quotes. The exception is when it is nessecary.
- There should be a space between the key word and the colon.
- There should be a space between the colon and the value.
- The comma should have no space before and 1 space behind itself.
- The last value shouldn't be trailed with a comma.
- The comma shouldn't start a new line. It should always trail the previous value.
good:
var obj = { A : 1, b : 2, C : 3 };
var obj = { A : 1,
b : 2,
C : 3
};
poor:
var obj = {A : 1, b : 2, C : 3};
var obj = { "A" : 1, "b" : 2, "C" : 3 };
var obj = { A: 1, b: 2, C: 3 };
var obj = { A :1, b :2, C :3 };
var obj = { A : 1 , b : 2 , C : 3 };
var obj = { A : 1,
b : 2,
C : 3,
};
var obj = { A : 1
, b : 2
, C : 3
};
- Arrays should always be created by
[]
and notnew Array()
. - When creating an empty Array, use
[]
without spaces. - When creating an Array with values,
- There should be a single space after the opening bracket.
- There should be a single space before the closing bracket.
- The comma should have no space before and 1 space behind itself.
- The last value shouldn't be trailed with a comma.
- The comma shouldn't start a new line. It should always trail the previous value.
good:
var arr = [ 1, 2, 3 ];
var arr = [ 1,
2,
3
];
poor:
var arr = [1, 2, 3];
var arr = [ 1 , 2 , 3 ];
var arr = [ 1,
2,
3,
];
var arr = [ 1
, 2
, 3
];
Lines are written using single quotes or double quotes:
good:
var lyrics = 'Never gonna Give you up, Never gonna Let you down' ;
var lyrics = "Never gonna Give you up, Never gonna Let you down" ;
Semicolon is always placed.
===============================================================This should still be written
Gaps
Keywords separated by a space: if ( test ) { / / ... }
function foo () { / / ... }
var bar = function () { / / ... }; Before the semicolon no space: return ; Braces
Opening brace is placed on the same line and separated by a space from the previous year: if ( test ) { / / ... }
function foo () { / / ... } Always put braces: Good:
if ( test ) { return ; } Poor:
if ( test ) return ;
if ( test ) return ;
if ( test ) { return ; } Conditional instructions
if
else written on the same line as the closing brace if ( test ) { / / ... } else { / / ... } Assignment in a conditional expression is not used: Good:
var foo = bar (); if ( foo > 0 ) { / / ... } Poor:
var foo ; if (( foo = bar ()) > 0 ) { / / ... } Expressions are used only where a value is required: Good:
if ( condition ) { actionIfTrue (); } else { actionIfFalse (); } Poor:
condition && actionIfTrue () | | actionIfFalse (); Long conditions that do not fit on one line, broken down as follows: if ( LongCondition | | anotherLongCondition && yetAnotherLongCondition ) { / / ... } Yoda conditions are used: Good:
if ( getType () === 'Driving' ) {
} Poor:
if ( 'Driving' === getType ()) {
} switch
Switch ( value ) { Case 1 : / / ... Break ;
case 2 :
/ / ...
Break ;
Default :
/ / ...
/ / no Break Keyword on the Last Case
} Cycles
for
As much as possible instead of for use Array.prototype.forEach :
[ 1 , 2 , 3 ]. forEach ( function ( value ) { console . Log ( value ); }); Code using forEach easier to read (it is easier to ignore what is happening in each iteration). Where speed is critical use plain for .
for (var i in obj)
As much as possible instead of for-in used Object.keys :
Object . keys ( obj ). forEach ( function ( Key ) { console . Log ( Key ); }); Operators
with
Operator with not used.
The equality operator
Always use strict equality === (inequality ! == ) if there is no need for typecasting.
Ternary operator
var x = A ? b : C ;
var y = A ? longButSimpleOperandB : longButSimpleOperandC ;
var z = A ? moreComplicatedB : moreComplicatedC ; Unary
All unary operators are written together with the following operands:
var foo = ! bar ; eval
Avoid using eval . To parse json using JSON.parse .
undefined
Check the value through a strict comparison.
Good:
x === undefined ; Poor:
/ / In modern browsers already defined immutable undefined. var undefined ; x === undefined ;
/ / Write more typeof x === 'undefined'
x === void 0 Parentheses
Put, unless it is necessary syntax or semantics. Not used with unary operators delete , typeof and void , as well as the keyword return , throw , New . Exceptions
Create exceptions using New Error :
Good:
throw New Error ( 'msg' ); Poor:
throw 'msg' ; Cast
Use explicit type:
Good:
Boolean ( foo ) Number ( bar ) String ( baz ) []. indexOf ( qux ) === - 1 or []. indexOf ( qux ) < 0 Poor:
!! foo
- bar baz + '' ~ []. indexOf ( qux ) Line breaks
The maximum string length of 120 characters if the string goes longer, made possible line breaks with appropriate indents after the transfer. Operators are placed on the previous line: var debt = this . calculateBaseDebt () + this . calculateSharedDebt () + this . calculateDebtPayments () + this . calculateDebtFine (); Closing parenthesis is not pressed against the portability code: Good:
DoSomethingThatRequiresALongFunctionName ( very_long_argument1 , argument2 , argument3 , argument4 ); anotherStatement ; Poor:
DoSomethingThatRequiresALongFunctionName ( very_long_argument1 , argument2 , argument3 , argument4 ); anotherStatement ; Concatenation
String concatenation operator is used + . Design []. join ('') is not used (this was true for older browsers). \ is used. Good:
var foo = 'A string of rather Long English text, an error message' + 'That Actually just Keeps going and going - an error' + 'message to make the Energizer bunny Blush (right through' + 'Those Shades Schwarzenegger)! Where was I? Oh Yes, ' + 'you ' ve Got an error and All the extraneous whitespace is' + 'just Gravy. Have A nice Day. ' ; Poor:
var foo = 'A string of rather Long English text, an error message \ Actually That just Keeps going and going - an error \ message to make the Energizer bunny Blush (right through \ Those Shades Schwarzenegger)! Where was I? Oh Yes, \ you \ 've Got an error and All the extraneous whitespace is \ just Gravy. Have A nice Day. ' ; Blank lines
Can be used to logically group sections of code:
doSomethingTo ( x ); doSomethingElseTo ( x ); andthen ( x );
nowDoSomethingWith ( y );
andNowWith ( z ); this circuit in
We recommend using Function.prototype.bind : doAsync ( function () { this . Fn (); }. bind ( this )); If the function allows you to pass this parameter, use it: Good:
[ 1 , 2 , 3 ]. forEach ( function ( n ) { this . Fn ( n ); }, this ); Poor:
[ 1 , 2 , 3 ]. forEach ( function ( n ) { this . Fn ( n ); }. bind ( this )); If you use a variable, call it _this : var _this = this ; doAsync ( function () { _this . Fn (); }); Comments
Comments written in Russian. To use inline comments / / . After / / put 1 space. Comments to the functions, classes, etc. written in the format JSDoc . Functions
Arguments
Choosing the function signature should be avoided Boolean Trap :
/ ** @ param {*} Boolean async
- / function fetchResults ( async ) {}
/ / On-call function is unclear, which means false. fetchResults ( false ); Use the following methods in order to avoid Boolean Trap:
Split method or function for a few: function fetchResultsSync () {} function fetchResultsAsync () {} Use constants, enumerations or static class field for the parameter values; / ** @ * Enum {Boolean}
- / var FetchMethod = { SYNC : false , ASYNC : true };
/ ** @ param {*} FetchMethod Method
- / function fetchResults ( Method ) {}
fetchResults ( FetchMethod . SYNC ); Just avoid Convinience Trap :
/ / Example of WebGL (without documentation are invited to guess what each number means and false) glCtx . vertexAttribPointer ( this . _glHandler , 4 , glCtx . FLOAT , false , 0 , 0 ); From Convinience Trap and Boolean Trap must use named parameters:
/ ** @ param {* Object} params
- @ param {Boolean} params.async
- / function fetchResults ( params ) {}
fetchResults ({ async : false });
glCtx . vertexAttribPointer ( this . _glHandler , { size : 4 , type : glCtx . FLOAT , normalizeData : false , stride : 0 , offset : 0 }); Classes
Listing of classes and inheritance is implemented using inherit . Destructor call Destruct () . "Symmetric" method is placed nearby. For example: var FooClass = inherit ({ __constructor : function () {},
/ / Destructor near designer
Destruct : function () {},
someMethod : function () {}
}); jQuery
jQuery only use for working with DOM . Implementation extend and inherit the same name lies in the individual modules. Depend on jQuery it should not be. jQuery.Deferred not used. PROMIS implemented using libraries vow and plugins Vow . node.js
Importing modules
All modules are imported at the beginning of the file immediately after describing to him if it is: Good:
var http = require ( 'http' ); var FS = require ( 'FS' );
/ / Code here Poor:
var http = require ( 'http' );
/ / Code here
var FS = require ( 'FS' );
/ / Code here Exception: modules imported on demand.
Imports should be grouped in the following order:
standard modules node.js modules party libraries modules for your application