[MUST] JavaScript Source files must be encoded in UTF-8 without BOM.
[MUST] 4 space indentation. tabs and 2 space are not allowed.
[MUST] case
and default
in switch
must be indented.
// good switch (variable) { case '1': // do... break; case '2': // do... break; default: // do... } // bad switch (variable) { case '1': // do... break; case '2': // do... break; default: // do... }
[MUST] Set off binary operator with spaces. But place no space between unary operator and its operand.
let a = !arr.length; a++; a = b + c;
[MUST] Place 1 space before the leading brace.
// good if (condition) { } set('attr', { some: 'xxx', any: 'yyy' }); function funcName() { } // bad if (condition){ } set('attr',{ some: 'xxx', any: 'yyy' }); function funcName(){ }
[MUST] Place 1 space after if
/ else
/ for
/ while
/ function
/ switch
/ do
/ try
/ catch
/ finally
.
// good if (condition) { } while (condition) { } (function () { })(); // bad if(condition) { } while(condition) { } (function() { })();
[MUST] In the object creating statement, place 1 space after :
, but no space before it.
// good const obj = { a: 1, b: 2, c: 3 }; // bad const obj = { a : 1, b:2, c :3 };
[MUST] Place no space between the function name and (
in function declaration, expression of named function and function call.
// good function funcName() { } const funcName = function funcName() { }; funcName(); // bad function funcName () { } const funcName = function funcName () { }; funcName ();
[MUST] Place no space between ,
and ;
.
// good callFunc(a, b); // bad callFunc(a , b) ;
[MUST] Place no space after (
and [
and before )
and ]
.
// good callFunc(param1, param2, param3); save(this.list[this.indexes[i]]); needIncream && (variable += increament); if (num > list.length) { } while (len--) { } // bad callFunc( param1, param2, param3 ); save( this.list[ this.indexes[ i ] ] ); needIncreament && ( variable += increament ); if ( num > list.length ) { } while ( len-- ) { } // good const arr1 = []; const arr2 = [1, 2, 3]; const obj1 = {}; const obj2 = {name: 'obj'}; const obj3 = { name: 'obj', age: 20, sex: 1 }; // bad const arr1 = [ ]; const arr2 = [ 1, 2, 3 ]; const obj1 = { }; const obj2 = { name: 'obj' }; const obj3 = {name: 'obj', age: 20, sex: 1};
[MUST] Must no trailing space in each line.
[MUST] Place line break in the end of a statement.
[MUST] No more than 120 characters per line.
[MUST] Place operator at the beginning of a line if it break lines.
// good if (user.isAuthenticated() && user.isInRole('admin') && user.hasAuthority('add-admin') || user.hasAuthority('delete-admin') ) { // Code } const result = number1 + number2 + number3 + number4 + number5; // bad if (user.isAuthenticated() && user.isInRole('admin') && user.hasAuthority('add-admin') || user.hasAuthority('delete-admin')) { // Code } const result = number1 + number2 + number3 + number4 + number5;
[MUST] Start a new line for )
, ]
, }
if the content inside the brackets occupies multiple lines. Make the same indent as the line where the corresponding (
, [
, {
placed.
// good if (product) { product.load(); if (user.isAuthenticated() && user.isInRole('admin') && user.hasAuthority('add-admin') ) { sendProduct(user, product); } } const arr = [ 'candy', 'sugar' ]; // bad if (product) { product.load(); if (user.isAuthenticated() && user.isInRole('admin') && user.hasAuthority('add-admin')) { sendProduct(user, product); } } const arr = [ 'candy', 'sugar' ];
[MUST] Must not break lines before ,
or ;
.
// good const obj = { a: 1, b: 2, c: 3 }; foo( aVeryVeryLongArgument, anotherVeryLongArgument, callback ); // bad const obj = { a: 1 , b: 2 , c: 3 }; foo( aVeryVeryLongArgument , anotherVeryLongArgument , callback );
[SUGGEST] Suggestion about line break and indent:
if (user.isAuthenticated() && user.isInRole('admin') && user.hasAuthority('add-admin') ) { // Code } foo( aVeryVeryLongArgument, anotherVeryLongArgument, callback ); baidu.format( dateFormatTemplate, year, month, date, hour, minute, second ); $('#items') .find('.selected') .highlight() .end(); const result = thisIsAVeryVeryLongCondition ? resultA : resultB; const res = condition ? thisIsAVeryVeryLongResult : resultB;
[MUST] Start a new line for else
and catch
if using multi-line blocks.
// good if (condition) { // some statements; } else { // some statements; } try { // some statements; } catch (ex) { // some statements; } // bad if (condition) { // some statements; } else { // some statements; } try { // some statements; } catch (ex) { // some statements; }
[MUST] The semicolon must not be ignored at the end of a statement.
[MUST] The {}
must not be ignored even if there is only one line.
// good if (condition) { callFunc(); } // bad if (condition) callFunc(); if (condition) callFunc();
[MUST] Place no semicolon at the end of a function definition.
// good function funcName() { } // bad function funcName() { }; // For function expression, the semicolon must not be ignored. const funcName = function () { };
[MUST] No trailing comma in object and array declarations.
// good const obj = { attr1: 'xxx', attr2: 'yyy' }; const arr = [ 'xxx', 'yyy' ]; // bad const obj = { attr1: 'xxx', attr2: 'yyy', }; const arr = [ 'xxx', 'yyy', ];
[MUST] Use lowerCamelCase for variables, properties and function names.
const loadingModules = {}; function loadProduct() { }
[MUST] Use UpperCamelCase (Pascal) for class names.
function Element(options) { }
[SUGGEST] All of the letters of a abbreviation should be both upper cases or both lower cases.
function parseSVG() { } const svgParser;
Language features can be polyfilled by some utilities, but must not by modifying the prototype of the built-in JS objects.
// good import * as zrUtil from 'zrender/src/core/util'; zrUtil.each(array, function (val, index) { sum += val; }); const result = zrUtil.map(array, function (val) { return parse(val); }); const pos = zrUtil.indexOf(array, val); const obj2 = zrUtil.extend({}, obj1); function Element() { // ... } // bad array.forEach(function (val, index) { sum += val; }); let result = array.map(function (val) { return parse(val); }); const pos = array.indexOf(val); const obj2 = Object.assign({}, obj1); class Element { // ... } String.prototype.trim = function () { };
[MUST] Prefer using const
to declare variable. And one line can not declares more than one variable.
// good const name = 'MyName'; const hangModules = []; const missModules = []; const visited = {}; // bad name = 'MyName'; const hangModules = [], missModules = [], visited = {};
[MUST] In equality expression, ==
can only be used on null
or undefined
detection. ===
should be used in the rest of cases .
// good if (age === 30) { // ... } if (type == null) { // ... } // bad if (age == 30) { // ...... }
[SUGGEST] Use xxx == null
to determine null
or undefined
.
[SUGGEST] Try best to make the meaning of null
and undefined
the same, namely, do not make users or developers distinguishing whether a variable is null
or undefined
.
[SUGGEST] The function expression or function declaration should not be placed inside a loop body.
// good function clicker() { // ...... } for (let i = 0, len = elements.length; i < len; i++) { const element = elements[i]; addListener(element, 'click', clicker); } // bad for (let i = 0, len = elements.length; i < len; i++) { const element = elements[i]; addListener(element, 'click', function () {}); }
[SUGGEST] Use + ''
to convert a value to string.
// good num + ''; // bad new String(num); num.toString(); String(num);
[SUGGEST] Use +
to convert a value to number.
// good +str; // bad Number(str);
[MUST] The second parameter must not be ignored when using parseInt
.
// good parseInt(str, 10); // bad parseInt(str);
[MUST] Use '
but not "
to define a string.
[MUST] Use object literal {}
to create a plain object.
// good const obj = {}; // bad const obj = new Object();
[MUST] If all of the properties of an object literal do not need quotation marks, they should ignore them. If quotation marks is necessary, use '
but not "
.
// good const info = { name: 'someone', age: 28 }; // bad const info = { 'name': 'someone', 'age': 28 }; const info2 = { "age": 40 };
[MUST] The prototype of built-in objects must not be modified.
// Forbidden String.prototype.trim = function () { };
[SUGGEST] Try best to use .
but not []
to visit properties of an object.
[SUGGEST] hasOwnProperty
should be used to when using for ... in ...
, in case that some extra properties is added on the prototype of Object
in some runtime environment.
const newInfo = {}; for (const key in info) { if (info.hasOwnProperty(key)) { newInfo[key] = info[key]; } }
[MUST] Use array literal []
to create an array, except intending to create an array with a given length.
// good const arr = []; const arr2 = new Array(1e4); // bad const arr = new Array();
[MUST] Do not use for in
in array traverse.
[MUST] Do not use eval
and with
. new Function
can be used.