Introduction to coding standards in Javascript (code examples)
This article brings you an introduction to coding standards in Javascript (code examples). It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.
Naming convention
Standard variables are named in camel case
'ID' is in the variable name All capital letters
Constants must be in all capital letters, connect constructors with underscores, and capitalize the first letter
jquery objects must start with '$' Naming
let thisIsMyName; let goodID; let reportURL; let AndroidVersion; let iOSVersion; let MAX_COUNT = 10; function Person(name) { this.name = name; } // not good let body = $('body'); // good let $body = $('body');
Local variable naming convention
s: represents a string. For example: sName, sHtml;
n: represents a number. For example: nPage, nTotal;
b: indicates logic. For example: bChecked, bHasLogin;
a: represents an array. For example: aList, aGroup;
r: represents a regular expression. For example: rDomain, rEmail;
f: represents a function. For example: fGetHtml, fInit;
o: Indicates other objects not mentioned above, such as: oButton, oDate;
Function naming
Humpback case naming method, you can use common verb conventions:
can determines whether an action can be performed, and the function returns a Boolean value. true: executable; false: not executable
has determines whether it contains a certain value, and the function returns a Boolean value. true: contains this value; false: does not contain this value
is determines whether it is a certain value, and the function returns a Boolean value. true: for a certain value; false: not for a certain value
get gets a certain value, the function returns a non-Boolean value
set sets a certain value, returns no value, returns whether the setting is successful, or returns a chained object. load loads certain data, returns no return value, or returns the result of whether the loading is completed
// 是否可阅读 function canRead() { return true; } // 获取名称 function getName() { return this.name; }
References
Use const for all references; do not use var.
eslint: prefer-const, no-const-assign
This ensures that you cannot reassign the reference, which can lead to bugs and difficult-to-understand code.
// bad var a = 1; var b = 2; // good const a = 1; const b = 2;
If you absolutely need mutable references, use let instead of var.
eslint: no-var jscs: disallowVar
// bad var count = 1; if (true) { count += 1; } // good, 使用 let. let count = 1; if (true) { count += 1; }
Objects
Use literal syntax to create objects.
eslint: no-new-object
// bad const item = new Object(); // good const item = {};
Use computed property names when creating objects with dynamic property names.
They allow you to define all properties of an object in one place.
function getKey(k) { return `a key named k`; } // bad const obj = { id: 5, name: 'San Francisco', }; obj[getKey('enabled')] = true; // good const obj = { id: 5, name: 'San Francisco', [getKey('enabled')]: true, };
Use object method shorthand syntax.
eslint: object-shorthand jscs: requireEnhancedObjectLiterals
// bad const atom = { value: 1, addValue: function (value) { return atom.value + value; }, }; // good const atom = { value: 1, addValue(value) { return atom.value + value; }, };
Use object property shorthand syntax.
eslint: object-shorthand jscs: requireEnhancedObjectLiterals
const lukeSkywalker = 'Luke Skywalker'; // bad const obj = { lukeSkywalker: lukeSkywalker, }; // good const obj = { lukeSkywalker, };
Write shorthand attribute grouping at the beginning of the object declaration
It is easier to see which properties are using shorthand syntax
const anakinSkywalker = 'Anakin Skywalker'; const lukeSkywalker = 'Luke Skywalker'; // bad const obj = { episodeOne: 1, twoJediWalkIntoACantina: 2, lukeSkywalker, episodeThree: 3, mayTheFourth: 4, anakinSkywalker, }; // good const obj = { lukeSkywalker, anakinSkywalker, episodeOne: 1, twoJediWalkIntoACantina: 2, episodeThree: 3, mayTheFourth: 4, };
Only quote attributes of invalid identifiers.
eslint: quote-props jscs: disallowQuotedKeysInObjects
Generally speaking, we think it is easier to read. It improves syntax highlighting and is easier to optimize by many JS engines.
// bad const bad = { 'foo': 3, 'bar': 4, 'data-blah': 5, }; // good const good = { foo: 3, bar: 4, 'data-blah': 5, };
Use the object spread operator to shallowly copy objects, taking precedence over Object.assign. Use the object remainder operator to obtain a new object with certain properties omitted.
// very bad const original = { a: 1, b: 2 }; const copy = Object.assign(original, { c: 3 }); // `original` 是可变的 ಠ_ಠ delete copy.a; // so does this // bad const original = { a: 1, b: 2 }; const copy = Object.assign({}, original, { c: 3 }); // copy => { a: 1, b: 2, c: 3 } // good const original = { a: 1, b: 2 }; const copy = { ...original, c: 3 }; // copy => { a: 1, b: 2, c: 3 } const { a, ...noA } = copy; // noA => { b: 2, c: 3 }
Array Arrays
Use literals to create arrays.
eslint: no-array-constructor
// bad const items = new Array(); // good const items = [];
Use the array spread operator... to copy the array.
// bad const len = items.length; const itemsCopy = []; let i; for (i = 0; i < len; i += 1) { itemsCopy[i] = items[i]; } // good const itemsCopy = [...items];
Use the spread operator ... instead of Array.from to convert an array-like object into an array.
const foo = document.querySelectorAll('.foo'); // good const nodes = Array.from(foo); // best const nodes = [...foo];
Use Array.from instead of the spread operator... to map iterations because it avoids creating an intermediary array.
// bad const baz = [...foo].map(bar); // good const baz = Array.from(foo, bar);
Destructuring Destructuring
Use object destructuring when accessing and using multiple properties of an object.
eslint: prefer-destructuring jscs: requireObjectDestructuring
// bad function getFullName(user) { const firstName = user.firstName; const lastName = user.lastName; return `firstName lastName`; } // good function getFullName(user) { const { firstName, lastName } = user; return `firstName lastName`; } // best function getFullName({ firstName, lastName }) { return `firstName lastName`; }
Use array destructuring.
eslint: prefer-destructuring jscs: requireArrayDestructuring
const arr = [1, 2, 3, 4]; // bad const first = arr[0]; const second = arr[1]; // good const [first, second] = arr;
Use object destructuring to achieve multiple return values instead of array destructuring. jscs: disallowArrayDestructuringReturn
You can add new properties or change the ordering over time without changing the position when it is called.
// bad function processInput(input) { return [left, right, top, bottom]; } // 调用者需要考虑返回数据的顺序 const [left, __, top] = processInput(input); // good function processInput(input) { return { left, right, top, bottom }; } // 调用者只选择他们需要的数据 const { left, top } = processInput(input);
Strings Strings
Use single quotes ‘’ for strings.
eslint: quotes jscs: validateQuoteMarks
// bad const name = "Capt. Janeway"; // bad - 模板字面量应该包含插值或换行符 const name = `Capt. Janeway`; // good const name = 'Capt. Janeway';
When building strings programmatically, use template strings instead of string concatenation.
eslint: prefer-template template-curly-spacing jscs: requireTemplateStrings
/ bad function sayHi(name) { return 'How are you, ' + name + '?'; } // bad function sayHi(name) { return ['How are you, ', name, '?'].join(); } // bad function sayHi(name) { return `How are you, ${ name }?`; } // good function sayHi(name) { return `How are you, name?`; }
Never use eval() on strings, it opens too many vulnerabilities.
eslint: no-eval
Functions
Use named function expressions instead of function declarations.
eslint: func-style jscs: disallowFunctionDeclarations
函数声明很容易被提升(Hoisting),这对可读性和可维护性来说都是不利的;
/ bad function foo() { // ... } // bad const foo = function () { // ... }; // good // 用明显区别于变量引用调用的词汇命名 const short = function longUniqueMoreDescriptiveLexicalFoo() { // ... };
用圆括号包裹立即调用函数表达式 (IIFE)。
eslint: wrap-iife jscs: requireParenthesesAroundIIFE
一个立即调用函数表达式是一个单独的单元 – 将函数表达式包裹在括号中,后面再跟一个调用括号,这看上去很紧凑。
// 立即调用函数表达式 (IIFE) (function () { console.log('Welcome to the Internet. Please follow me.'); }());
不要使用 arguments。可以选择 rest 语法 … 替代。
使用 … 能明确你要传入的参数。另外 rest(剩余)参数是一个真正的数组,而 arguments 是一个类数组(Array-like)。
// bad function concatenateAll() { const args = Array.prototype.slice.call(arguments); return args.join(''); } // good function concatenateAll(...args) { return args.join(''); }
使用默认参数语法,而不要使用一个变化的函数参数
// really bad function handleThings(opts) { // 更加糟糕: 如果参数 opts 是 falsy(假值) 的话,它将被设置为一个对象, // 这可能是你想要的,但它可以引起一些小的错误。 opts = opts || {}; // ... } // still bad function handleThings(opts) { if (opts === void 0) { opts = {}; } // ... } // good function handleThings(opts = {}) { // ... }
始终将默认参数放在最后。
// bad function handleThings(opts = {}, name) { // ... } // good function handleThings(name, opts = {}) { // ... }
隔开函数签名,括号两边用空格隔开。
// bad const f = function(){}; const g = function (){}; const h = function() {}; // good const x = function () {}; const y = function a() {};
不要改变参数。
eslint: no-param-reassign
操作作为参数传入的对象,可能会在调用原始对象时造成不必要的变量副作用。(对象是引用类型)
// bad function f1(obj) { obj.key = 1; } // good function f2(obj) { const key = Object.prototype.hasOwnProperty.call(obj, 'key') ? obj.key : 1; }
箭头函数 Arrow Functions
当您必须使用匿名函数(如在传递一个内联回调时),请使用箭头函数表示法。
eslint: prefer-arrow-callback, arrow-spacing jscs: requireArrowFunctions
它创建了一个在 this 上下文中执行的函数的版本,这通常是你想要的,而且这样的写法更为简洁。
// bad [1, 2, 3].map(function (x) { const y = x + 1; return x * y; }); // bad [1, 2, 3].map( _ => { return 0; }); // good [1, 2, 3].map((x) => { const y = x + 1; return x * y; }); // good [1, 2, 3].map(() => { return 0; });
如果函数体由一个返回无副作用(side effect)的expression(表达式)的单行语句组成,那么可以省略大括号并使用隐式返回。否则,保留大括号并使用 return 语句。
// bad [1, 2, 3].map(number => { const nextNumber = number + 1; return `A string containing the nextNumber.`; }); // good [1, 2, 3].map(number => `A string containing the number.`);
如果表达式跨多行,将其包裹在括号中,可以提高可读性。
// bad ['get', 'post', 'put'].map(httpMethod => Object.prototype.hasOwnProperty.call( httpMagicObjectWithAVeryLongName, httpMethod, ) ); // good ['get', 'post', 'put'].map(httpMethod => ( Object.prototype.hasOwnProperty.call( httpMagicObjectWithAVeryLongName, httpMethod, ) ));
如果你的函数只有一个参数并且不使用大括号,则可以省略参数括号。否则,为了清晰和一致性,总是给参数加上括号。
// bad [1, 2, 3].map((x) => x * x); // good [1, 2, 3].map(x => x * x); // good [1, 2, 3].map(number => ( `A long string with the number. It’s so long that we don’t want it to take up space on the .map line!` )); // 总是添加() // bad [1, 2, 3].map(x => { const y = x + 1; return x * y; }); // good [1, 2, 3].map((x) => { const y = x + 1; return x * y; });
避免使用比较运算符(< =, >=)时,混淆箭头函数语法(=>)。
// bad const itemHeight = item => item.height > 256 ? item.largeSize : item.smallSize; // bad const itemHeight = (item) => item.height > 256 ? item.largeSize : item.smallSize; // good const itemHeight = item => (item.height > 256 ? item.largeSize : item.smallSize); // good const itemHeight = (item) => { const { height, largeSize, smallSize } = item; return height > 256 ? largeSize : smallSize; };
类 Classes & 构造函数 Constructors
总是使用 *class。避免直接操作 prototype 。
// bad function Queue(contents = []) { this.queue = [...contents]; } Queue.prototype.pop = function () { const value = this.queue[0]; this.queue.splice(0, 1); return value; }; // good class Queue { constructor(contents = []) { this.queue = [...contents]; } pop() { const value = this.queue[0]; this.queue.splice(0, 1); return value; } }
使用 extends 继承。
因为 extends 是一个内置的原型继承方法并且不会破坏 instanceof。
// bad const inherits = require('inherits'); function PeekableQueue(contents) { Queue.apply(this, contents); } inherits(PeekableQueue, Queue); PeekableQueue.prototype.peek = function () { return this.queue[0]; }; // good class PeekableQueue extends Queue { peek() { return this.queue[0]; } }
如果没有指定,类有一个默认的构造函数。一个空的构造函数或者只是委托给父类则不是必须的。
eslint: no-useless-constructor
// bad class Jedi { constructor() {} getName() { return this.name; } } // bad class Rey extends Jedi { constructor(...args) { super(...args); } } // good class Rey extends Jedi { constructor(...args) { super(...args); this.name = 'Rey'; } }
避免重复类成员。
eslint: no-dupe-class-members
// bad class Foo { bar() { return 1; } bar() { return 2; } } // good class Foo { bar() { return 1; } } // good class Foo { bar() { return 2; } }
模块 Modules
总是使用模块 (import/export) 而不是其他非标准模块系统。
// bad const AirbnbStyleGuide = require('./AirbnbStyleGuide'); module.exports = AirbnbStyleGuide.es6; // ok import AirbnbStyleGuide from './AirbnbStyleGuide'; export default AirbnbStyleGuide.es6; // best import { es6 } from './AirbnbStyleGuide'; export default es6;
不要使用通配符 import(导入)。
这样能确保你只有一个默认 export(导出)。
// bad import * as AirbnbStyleGuide from './AirbnbStyleGuide'; // good import AirbnbStyleGuide from './AirbnbStyleGuide';
不要从 import(导入) 中直接 export(导出)。
虽然一行代码简洁明了,但有一个明确的 import(导入) 方法和一个明确的 export(导出) 方法,使事情能保持一致。
// bad // filename es6.js export { es6 as default } from './AirbnbStyleGuide'; // good // filename es6.js import { es6 } from './AirbnbStyleGuide'; export default es6;
一个地方只在一个路径中 import(导入) 。
// bad import foo from 'foo'; // … 其他一些 imports … // import { named1, named2 } from 'foo'; // good import foo, { named1, named2 } from 'foo'; // good import foo, { named1, named2, } from 'foo';
不要 export(导出) 可变绑定。
eslint: import/no-mutable-exports
一般应该避免可变性,特别是在导出可变绑定时。虽然一些特殊情况下,可能需要这种技术,但是一般而言,只应该导出常量引用。
// bad let foo = 3; export { foo }; // good const foo = 3; export { foo };
在只有单个导出的模块中,默认 export(导出) 优于命名 export(导出)。
eslint: import/prefer-default-export
为了鼓励更多的文件只有一个 export(导出),这有利于模块的可读性和可维护性。
// bad export function foo() {} // good export default function foo() {}
将所有 import 导入放在非导入语句的上面。
eslint: import/first
由于 import 被提升,保持他们在顶部,防止意外的行为。
// bad import foo from 'foo'; foo.init(); import bar from 'bar'; // good import foo from 'foo'; import bar from 'bar'; foo.init();
多行导入应该像多行数组和对象字面量一样进行缩进。
// bad import {longNameA, longNameB, longNameC, longNameD, longNameE} from 'path'; // good import { longNameA, longNameB, longNameC, longNameD, longNameE, } from 'path';
属性 Properties
使用 点语法(.) 来访问对象的属性。
eslint: dot-notation jscs: requireDotNotation
const luke = { jedi: true, age: 28, }; // bad const isJedi = luke['jedi']; // good const isJedi = luke.jedi;
当通过变量访问属性时使用中括号 []。
const luke = { jedi: true, age: 28, }; function getProp(prop) { return luke[prop]; } const isJedi = getProp('jedi');
求幂时使用求幂运算符 ** 。
eslint: no-restricted-properties.
// bad const binary = Math.pow(2, 10); // good const binary = 2 ** 10;
变量 Variables
总是使用 const 或 let 来声明变量。 不这样做会导致产生全局变量。 我们希望避免污染全局命名空间。
eslint: no-undef prefer-const
// bad superPower = new SuperPower(); // good const superPower = new SuperPower();
将所有的 const 和 let 分组 。
当你需要把已分配的变量分配给一个变量时非常有用
// bad let i, len, dragonball, items = getItems(), goSportsTeam = true; // bad let i; const items = getItems(); let dragonball; const goSportsTeam = true; let len; // good const goSportsTeam = true; const items = getItems(); let dragonball; let i; let length;
变量不要链式赋值。
eslint: no-multi-assign
链接变量赋值会创建隐式全局变量。
// bad (function example() { // JavaScript 将其解析为 // let a = ( b = ( c = 1 ) ); // let关键字只适用于变量a; // 变量b和c变成了全局变量。 let a = b = c = 1; }()); console.log(a); // 抛出 ReferenceError(引用错误) console.log(b); // 1 console.log(c); // 1 // good (function example() { let a = 1; let b = a; let c = a; }()); console.log(a); // 抛出 ReferenceError(引用错误) console.log(b); // 抛出 ReferenceError(引用错误) console.log(c); // 抛出 ReferenceError(引用错误) // 同样适用于 `const`
避免使用一元递增和递减运算符(++, –)。
根据 eslint 文档,一元递增和递减语句会受到自动插入分号的影响,并可能导致应用程序中的值递增或递减,从而导致无提示错误。使用像 num += 1 而不是 num++ 或 num ++ 这样的语句来改变你的值也更具有表现力。不允许一元递增和递减语句也会阻止您无意中预先递增/递减值,这也会导致程序中的意外行为。
// bad const array = [1, 2, 3]; let num = 1; num++; --num; let sum = 0; let truthyCount = 0; for (let i = 0; i < array.length; i++) { let value = array[i]; sum += value; if (value) { truthyCount++; } } // good const array = [1, 2, 3]; let num = 1; num += 1; num -= 1; const sum = array.reduce((a, b) => a + b, 0); const truthyCount = array.filter(Boolean).length;
比较运算符 Comparison Operators 和 等号 Equality
使用 === 和 !== 优先于 == 和 !=。
eslint: eqeqeq
对于布尔值使用简写,但对于字符串和数字使用显式比较。
// bad if (isValid === true) { // ... } // good if (isValid) { // ... } // bad if (name) { // ... } // good if (name !== '') { // ... } // bad if (collection.length) { // ... } // good if (collection.length > 0) { // ... }
在 case 和 default 子句中,使用大括号来创建包含词法声明的语句块(例如 let, const, function, 和 class).
eslint: no-case-declarations
// bad switch (foo) { case 1: let x = 1; break; case 2: const y = 2; break; case 3: function f() { // ... } break; default: class C {} } // good switch (foo) { case 1: { let x = 1; break; } case 2: { const y = 2; break; } case 3: { function f() { // ... } break; } case 4: bar(); break; default: { class C {} } }
三元表达式不应该嵌套,通常写成单行表达式。
eslint: no-nested-ternary
// bad const foo = maybe1 > maybe2 ? "bar" : value1 > value2 ? "baz" : null; // 拆分成2个分离的三元表达式 const maybeNull = value1 > value2 ? 'baz' : null; // better const foo = maybe1 > maybe2 ? 'bar' : maybeNull; // best const foo = maybe1 > maybe2 ? 'bar' : maybeNull;
避免不必要的三元表达式语句。
eslint: no-unneeded-ternary
/ bad const foo = a ? a : b; const bar = c ? true : false; const baz = c ? false : true; // good const foo = a || b; const bar = !!c; const baz = !c;
当运算符混合在一个语句中时,请将其放在括号内。混合算术运算符时,不要将 * 和 % 与 + , -,,/ 混合在一起。
eslint: no-mixed-operators
这可以提高可读性,并清晰展现开发者的意图。
/ bad const foo = a && b < 0 || c > 0 || d + 1 === 0; // bad const bar = a ** b - 5 % d; // bad if (a || b && c) { return d; } // good const foo = (a && b < 0) || c > 0 || (d + 1 === 0); // good const bar = (a ** b) - (5 % d); // good if ((a || b) && c) { return d; } // good const bar = a + b / c * d;
代码块 Blocks
使用大括号包裹所有的多行代码块。
eslint: nonblock-statement-body-position
// bad if (test) return false; // good if (test) return false; // good if (test) { return false; } // bad function foo() { return false; } // good function bar() { return false; }
如果通过 if 和 else 使用多行代码块,把 else 放在 if 代码块闭合括号的同一行。
eslint: brace-style
// bad if (test) { thing1(); thing2(); } else { thing3(); } // good if (test) { thing1(); thing2(); } else { thing3(); }
如果一个 if 块总是执行一个 return 语句,后面的 else 块是不必要的。在 else if 块中的 return,可以分成多个 if 块来 return 。
eslint: no-else-return
// bad function foo() { if (x) { return x; } else { return y; } } // bad function cats() { if (x) { return x; } else if (y) { return y; } } // bad function dogs() { if (x) { return x; } else { if (y) { return y; } } } // good function foo() { if (x) { return x; } return y; } // good function cats() { if (x) { return x; } if (y) { return y; } } //good function dogs(x) { if (x) { if (z) { return y; } } else { return z; } }
控制语句 Control Statements
如果您的控制语句(if, while 的)太长或超过最大行长度,那么每个(分组)条件可以放单独一行。逻辑运算符应该放在每行起始处。
// bad if ((foo === 123 || bar === 'abc') && doesItLookGoodWhenItBecomesThatLong() && isThisReallyHappening()) { thing1(); } // bad if (foo === 123 && bar === 'abc') { thing1(); } // bad if (foo === 123 && bar === 'abc') { thing1(); } // bad if ( foo === 123 && bar === 'abc' ) { thing1(); } // good if ( foo === 123 && bar === 'abc' ) { thing1(); } // good if ( (foo === 123 || bar === "abc") && doesItLookGoodWhenItBecomesThatLong() && isThisReallyHappening() ) { thing1(); } // good if (foo === 123 && bar === 'abc') { thing1(); }
注释 Comments
多行注释使用 /* … /。
/** * @param {Grid} grid 需要合并的Grid * @param {Array} cols 需要合并列的Index(序号)数组;从0开始计数,序号也包含。 * @param {Boolean} isAllSome 是否2个tr的cols必须完成一样才能进行合并。true:完成一样;false(默认):不完全一样 * @return void * @author 单志永 2018/11/8 */ function mergeCells(grid, cols, isAllSome) { // Do Something }
单行注释使用 // 。将单行注释放在续注释的语句上方。在注释之前放置一个空行,除非它位于代码块的第一行。
// bad const active = true; // is current tab // good // is current tab const active = true; // bad function getType() { console.log('fetching type...'); // set the default type to 'no type' const type = this.type || 'no type'; return type; } // good function getType() { console.log('fetching type...'); // set the default type to 'no type' const type = this.type || 'no type'; return type; } // also good function getType() { // set the default type to 'no type' const type = this.type || 'no type'; return type; }
所有注释符和注释内容用一个空格隔开,让它更容易阅读。
eslint: spaced-comment
// bad //is current tab const active = true; // good // is current tab const active = true; // bad /** *make() returns a new element *based on the passed-in tag name */ function make(tag) { // ... return element; } // good /** * make() returns a new element * based on the passed-in tag name */ function make(tag) { // ... return element; }
给注释增加 FIXME 或 TODO 的前缀,可以帮助其他开发者快速了解这个是否是一个需要重新复查的问题,或是你正在为需要解决的问题提出解决方案。这将有别于常规注释,因为它们是可操作的。使用 FIXME – need to figure this out 或者 TODO – need to implement。
使用 // FIXME: 来标识需要修正的问题。注:如果代码中有该标识,说明标识处代码需要修正,甚至代码是错误的,不能工作,需要修复,如何修正会在说明中简略说明。
lass Calculator extends Abacus { constructor() { super(); // FIXME: shouldn’t use a global here total = 0; } }
使用 // TODO: 来标识需要实现的问题。注:如果代码中有该标识,说明在标识处有功能代码待编写,待实现的功能在说明中会简略说明。
class Calculator extends Abacus { constructor() { super(); // TODO: total should be configurable by an options param this.total = 0; } }
空格 Whitespace
使用 2 个空格作为缩进
// bad function foo() { ∙∙∙∙let name; } // bad function bar() { ∙let name; } // good function baz() { ∙∙let name; }
在大括号前放置 1 个空格。
eslint: space-before-blocks jscs: requireSpaceBeforeBlockStatements
// bad function test(){ console.log('test'); } // good function test() { console.log('test'); } // bad dog.set('attr',{ age: '1 year', breed: 'Bernese Mountain Dog', }); // good dog.set('attr', { age: '1 year', breed: 'Bernese Mountain Dog', });
在控制语句(if、while 等)的小括号前放一个空格。在函数调用及声明中,不在函数的参数列表前加空格。
eslint: keyword-spacing jscs: requireSpaceAfterKeywords
// bad if(isJedi) { fight (); } // good if (isJedi) { fight(); } // bad function fight () { console.log ('Swooosh!'); } // good function fight() { console.log('Swooosh!'); }
使用空格把运算符隔开。
eslint: space-infix-ops jscs: requireSpaceBeforeBinaryOperators, requireSpaceAfterBinaryOperators
// bad const x=y+5; // good const x = y + 5;
在文件末尾插入一个空行。
eslint: eol-last
// bad import { es6 } from './AirbnbStyleGuide'; // ... export default es6; // bad import { es6 } from './AirbnbStyleGuide'; // ... export default es6; // good import { es6 } from './AirbnbStyleGuide'; // ... export default es6;
长方法链式调用时使用缩进(2个以上的方法链式调用)。使用一个点 . 开头,强调该行是一个方法调用,不是一个新的声明。
eslint: newline-per-chained-call no-whitespace-before-property
// bad $('#items').find('.selected').highlight().end().find('.open').updateCount(); // bad $('#items'). find('.selected'). highlight(). end(). find('.open'). updateCount(); // good $('#items') .find('.selected') .highlight() .end() .find('.open') .updateCount(); // bad const leds = stage.selectAll('.led').data(data).enter().append('svg:svg').classed('led', true) .attr('width', (radius + margin) * 2).append('svg:g') .attr('transform', `translate(${radius + margin},${radius + margin})`) .call(tron.led); // good const leds = stage.selectAll('.led') .data(data) .enter().append('svg:svg') .classed('led', true) .attr('width', (radius + margin) * 2) .append('svg:g') .attr('transform', `translate(${radius + margin},${radius + margin})`) .call(tron.led); // good const leds = stage.selectAll('.led').data(data);
不要在圆括号内加空格。
// bad function bar( foo ) { return foo; } // good function bar(foo) { return foo; } // bad if ( foo ) { console.log(foo); } // good if (foo) { console.log(foo); }
不要在中括号内添加空格。
eslint: array-bracket-spacing jscs: disallowSpacesInsideArrayBrackets
// bad const foo = [ 1, 2, 3 ]; console.log(foo[ 0 ]); // good const foo = [1, 2, 3]; console.log(foo[0]);
在大括号内添加空格
// bad const foo = {clark: 'kent'}; // good const foo = { clark: 'kent' };
类型转换 Type Casting & Coercion
在声明语句的开始处就执行强制类型转换.
字符串:
eslint: no-new-wrappers
// => this.reviewScore = 9; // bad const totalScore = new String(this.reviewScore); // typeof totalScore 是 "object" 而不是 "string" // bad const totalScore = this.reviewScore + ''; // 调用 this.reviewScore.valueOf() // bad const totalScore = this.reviewScore.toString(); // 不能保证返回一个字符串 // good const totalScore = String(this.reviewScore);
使数字: 使用 Number 进行转换,而 parseInt 则始终以基数解析字串。
eslint: radix no-new-wrappers
const inputValue = '4'; // bad const val = new Number(inputValue); // bad const val = +inputValue; // bad const val = inputValue >> 0; // bad const val = parseInt(inputValue); // good const val = Number(inputValue); // good const val = parseInt(inputValue, 10);
布尔值:
eslint: no-new-wrappers
const age = 0; // bad const hasAge = new Boolean(age); // good const hasAge = Boolean(age); // best const hasAge = !!age;
命名规则 Naming Conventions
避免使用单字母名称。使你的命名具有描述性。
eslint: id-length
// bad function q() { // ... } // good function query() { // ... }
当命名对象,函数和实例时使用驼峰式命名。
eslint: camelcase jscs: requireCamelCaseOrUpperCaseIdentifiers
// bad const OBJEcttsssss = {}; const this_is_my_object = {}; function c() {} // good const thisIsMyObject = {}; function thisIsMyFunction() {}
当命名构造函数或类的时候使用 PascalCase 式命名,(注:即单词首字母大写)。
eslint: new-cap
// bad function user(options) { this.name = options.name; } const bad = new user({ name: 'nope', }); // good class User { constructor(options) { this.name = options.name; } } const good = new User({ name: 'yup', });
当 导出(export) 一个默认函数时使用驼峰式命名。你的文件名应该和你的函数的名字一致。
function makeStyleGuide() { // ... } export default makeStyleGuide;
当导出一个 构造函数 / 类 / 单例 / 函数库 / 纯对象时使用 PascalCase 式命名,(愚人码头注:即单词首字母大写)。
const AirbnbStyleGuide = { es6: { }, }; export default AirbnbStyleGuide;
存取器 Accessors
属性的存取器函数不是必须的。
別使用 JavaScript 的 getters/setters,因为它们会导致意想不到的副作用,而且很难测试,维护和理解。相反,如果要使用存取器函数,使用 getVal() 及 setVal(‘hello’)。
// bad class Dragon { get age() { // ... } set age(value) { // ... } } // good class Dragon { getAge() { // ... } setAge(value) { // ... } }
如果属性/方法是一个 boolean, 使用 isVal() 或 hasVal() 方法。
// bad if (!dragon.age()) { return false; } // good if (!dragon.hasAge()) { return false; } )
The above is the detailed content of Introduction to coding standards in Javascript (code examples). For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



How to use WebSocket and JavaScript to implement an online speech recognition system Introduction: With the continuous development of technology, speech recognition technology has become an important part of the field of artificial intelligence. The online speech recognition system based on WebSocket and JavaScript has the characteristics of low latency, real-time and cross-platform, and has become a widely used solution. This article will introduce how to use WebSocket and JavaScript to implement an online speech recognition system.

WebSocket and JavaScript: Key technologies for realizing real-time monitoring systems Introduction: With the rapid development of Internet technology, real-time monitoring systems have been widely used in various fields. One of the key technologies to achieve real-time monitoring is the combination of WebSocket and JavaScript. This article will introduce the application of WebSocket and JavaScript in real-time monitoring systems, give code examples, and explain their implementation principles in detail. 1. WebSocket technology

Introduction to how to use JavaScript and WebSocket to implement a real-time online ordering system: With the popularity of the Internet and the advancement of technology, more and more restaurants have begun to provide online ordering services. In order to implement a real-time online ordering system, we can use JavaScript and WebSocket technology. WebSocket is a full-duplex communication protocol based on the TCP protocol, which can realize real-time two-way communication between the client and the server. In the real-time online ordering system, when the user selects dishes and places an order

How to use WebSocket and JavaScript to implement an online reservation system. In today's digital era, more and more businesses and services need to provide online reservation functions. It is crucial to implement an efficient and real-time online reservation system. This article will introduce how to use WebSocket and JavaScript to implement an online reservation system, and provide specific code examples. 1. What is WebSocket? WebSocket is a full-duplex method on a single TCP connection.

JavaScript and WebSocket: Building an efficient real-time weather forecast system Introduction: Today, the accuracy of weather forecasts is of great significance to daily life and decision-making. As technology develops, we can provide more accurate and reliable weather forecasts by obtaining weather data in real time. In this article, we will learn how to use JavaScript and WebSocket technology to build an efficient real-time weather forecast system. This article will demonstrate the implementation process through specific code examples. We

JavaScript tutorial: How to get HTTP status code, specific code examples are required. Preface: In web development, data interaction with the server is often involved. When communicating with the server, we often need to obtain the returned HTTP status code to determine whether the operation is successful, and perform corresponding processing based on different status codes. This article will teach you how to use JavaScript to obtain HTTP status codes and provide some practical code examples. Using XMLHttpRequest

Usage: In JavaScript, the insertBefore() method is used to insert a new node in the DOM tree. This method requires two parameters: the new node to be inserted and the reference node (that is, the node where the new node will be inserted).

JavaScript is a programming language widely used in web development, while WebSocket is a network protocol used for real-time communication. Combining the powerful functions of the two, we can create an efficient real-time image processing system. This article will introduce how to implement this system using JavaScript and WebSocket, and provide specific code examples. First, we need to clarify the requirements and goals of the real-time image processing system. Suppose we have a camera device that can collect real-time image data
