Home > Web Front-end > JS Tutorial > body text

Introduction to coding standards in Javascript (code examples)

不言
Release: 2019-02-27 10:46:21
forward
2319 people have browsed it

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');
Copy after login

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;
}
Copy after login

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;
Copy after login

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;
}
Copy after login

Objects

Use literal syntax to create objects.

eslint: no-new-object

// bad
const item = new Object();
// good
const item = {};
Copy after login

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,
};
Copy after login

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;
  },
};
Copy after login

Use object property shorthand syntax.

eslint: object-shorthand jscs: requireEnhancedObjectLiterals

const lukeSkywalker = 'Luke Skywalker';
// bad
const obj = {
  lukeSkywalker: lukeSkywalker,
};
// good
const obj = {
  lukeSkywalker,
};
Copy after login

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,
};
Copy after login

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,
};
Copy after login

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 }
Copy after login

Array Arrays

Use literals to create arrays.

eslint: no-array-constructor

// bad
const items = new Array();
// good
const items = [];
Copy after login

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];
Copy after login

Use the spread operator ... instead of Array.from to convert an array-like object into an array.

const foo = document.querySelectorAll(&#39;.foo&#39;);
// good
const nodes = Array.from(foo);
// best
const nodes = [...foo];
Copy after login

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);
Copy after login

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`;
}
Copy after login

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;
Copy after login

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);
Copy after login

Strings Strings

Use single quotes ‘’ for strings.

eslint: quotes jscs: validateQuoteMarks

// bad
const name = "Capt. Janeway";
// bad - 模板字面量应该包含插值或换行符
const name = `Capt. Janeway`;
// good
const name = &#39;Capt. Janeway&#39;;
Copy after login

When building strings programmatically, use template strings instead of string concatenation.

eslint: prefer-template template-curly-spacing jscs: requireTemplateStrings

/ bad
function sayHi(name) {
  return &#39;How are you, &#39; + name + &#39;?&#39;;
}
// bad
function sayHi(name) {
  return [&#39;How are you, &#39;, name, &#39;?&#39;].join();
}
// bad
function sayHi(name) {
  return `How are you, ${ name }?`;
}
// good
function sayHi(name) {
   return `How are you, name?`;
}
Copy after login

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() {
  // ...
};
Copy after login

用圆括号包裹立即调用函数表达式 (IIFE)。

eslint: wrap-iife jscs: requireParenthesesAroundIIFE

一个立即调用函数表达式是一个单独的单元 – 将函数表达式包裹在括号中,后面再跟一个调用括号,这看上去很紧凑。
// 立即调用函数表达式 (IIFE)
(function () {
console.log(&#39;Welcome to the Internet. Please follow me.&#39;);
}());
Copy after login

不要使用 arguments。可以选择 rest 语法 … 替代。

使用 … 能明确你要传入的参数。另外 rest(剩余)参数是一个真正的数组,而 arguments 是一个类数组(Array-like)。
// bad
function concatenateAll() {
  const args = Array.prototype.slice.call(arguments);
  return args.join(&#39;&#39;);
}
// good
function concatenateAll(...args) {
  return args.join(&#39;&#39;);
}
Copy after login

使用默认参数语法,而不要使用一个变化的函数参数

// really bad
function handleThings(opts) {
  // 更加糟糕: 如果参数 opts 是 falsy(假值) 的话,它将被设置为一个对象,
  // 这可能是你想要的,但它可以引起一些小的错误。
  opts = opts || {};
  // ...
}
// still bad
function handleThings(opts) {
  if (opts === void 0) {
  opts = {};
}
// ...
}
// good
function handleThings(opts = {}) {
  // ...
}
Copy after login

始终将默认参数放在最后。

// bad
function handleThings(opts = {}, name) {
// ...
}
// good
function handleThings(name, opts = {}) {
// ...
}
Copy after login

隔开函数签名,括号两边用空格隔开。

// bad
const f = function(){};
const g = function (){};
const h = function() {};
// good
const x = function () {};
const y = function a() {};
Copy after login

不要改变参数。

eslint: no-param-reassign

操作作为参数传入的对象,可能会在调用原始对象时造成不必要的变量副作用。(对象是引用类型)
// bad
function f1(obj) {
obj.key = 1;
}
// good
function f2(obj) {
  const key = Object.prototype.hasOwnProperty.call(obj, &#39;key&#39;) ? obj.key : 1;
}
Copy after login

箭头函数 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;
});
Copy after login

如果函数体由一个返回无副作用(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.`);
Copy after login

如果表达式跨多行,将其包裹在括号中,可以提高可读性。

// bad
['get', 'post', 'put'].map(httpMethod => Object.prototype.hasOwnProperty.call(
  httpMagicObjectWithAVeryLongName,
  httpMethod,
  )
);
// good
['get', 'post', 'put'].map(httpMethod => (
  Object.prototype.hasOwnProperty.call(
  httpMagicObjectWithAVeryLongName,
  httpMethod,
  )
));
Copy after login

如果你的函数只有一个参数并且不使用大括号,则可以省略参数括号。否则,为了清晰和一致性,总是给参数加上括号。

// 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;
});
Copy after login

避免使用比较运算符(< =, >=)时,混淆箭头函数语法(=>)。

// 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;
};
Copy after login

类 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;
  }
}
Copy after login

使用 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];
  }
}
Copy after login

如果没有指定,类有一个默认的构造函数。一个空的构造函数或者只是委托给父类则不是必须的。

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';
  }
}
Copy after login

避免重复类成员。

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; }
}
Copy after login

模块 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;
Copy after login

不要使用通配符 import(导入)。

这样能确保你只有一个默认 export(导出)。
// bad
import * as AirbnbStyleGuide from './AirbnbStyleGuide';
// good
import AirbnbStyleGuide from './AirbnbStyleGuide';
Copy after login

不要从 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;
Copy after login

一个地方只在一个路径中 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';
Copy after login

不要 export(导出) 可变绑定。

eslint: import/no-mutable-exports

一般应该避免可变性,特别是在导出可变绑定时。虽然一些特殊情况下,可能需要这种技术,但是一般而言,只应该导出常量引用。
// bad
let foo = 3;
export { foo };
// good
const foo = 3;
export { foo };
Copy after login

在只有单个导出的模块中,默认 export(导出) 优于命名 export(导出)。

eslint: import/prefer-default-export

为了鼓励更多的文件只有一个 export(导出),这有利于模块的可读性和可维护性。
// bad
export function foo() {}
// good
export default function foo() {}
Copy after login

将所有 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();
Copy after login

多行导入应该像多行数组和对象字面量一样进行缩进。

// bad
import {longNameA, longNameB, longNameC, longNameD, longNameE} from 'path';
// good
import {
longNameA,
longNameB,
longNameC,
longNameD,
longNameE,
} from 'path';
Copy after login

属性 Properties

使用 点语法(.) 来访问对象的属性。

eslint: dot-notation jscs: requireDotNotation

const luke = {
jedi: true,
age: 28,
};
// bad
const isJedi = luke['jedi'];
// good
const isJedi = luke.jedi;
Copy after login

当通过变量访问属性时使用中括号 []。

const luke = {
jedi: true,
age: 28,
};
function getProp(prop) {
return luke[prop];
}
const isJedi = getProp('jedi');
Copy after login

求幂时使用求幂运算符 ** 。

eslint: no-restricted-properties.

// bad
const binary = Math.pow(2, 10);
// good
const binary = 2 ** 10;
Copy after login

变量 Variables

总是使用 const 或 let 来声明变量。 不这样做会导致产生全局变量。 我们希望避免污染全局命名空间。

eslint: no-undef prefer-const

// bad
superPower = new SuperPower();
// good
const superPower = new SuperPower();
Copy after login

将所有的 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;
Copy after login

变量不要链式赋值。

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`
Copy after login

避免使用一元递增和递减运算符(++, –)。

根据 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;
Copy after login

比较运算符 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) {
// ...
}
Copy after login

在 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 {}
  }
}
Copy after login

三元表达式不应该嵌套,通常写成单行表达式。

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;
Copy after login

避免不必要的三元表达式语句。

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;
Copy after login

当运算符混合在一个语句中时,请将其放在括号内。混合算术运算符时,不要将 * 和 % 与 + , -,,/ 混合在一起。

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;
Copy after login

代码块 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;
}
Copy after login

如果通过 if 和 else 使用多行代码块,把 else 放在 if 代码块闭合括号的同一行。

eslint: brace-style

// bad
if (test) {
  thing1();
  thing2();
}
else {
  thing3();
}
// good
if (test) {
  thing1();
  thing2();
} else {
  thing3();
}
Copy after login

如果一个 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;
  }
}
Copy after login

控制语句 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();
}
Copy after login

注释 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
}
Copy after login

单行注释使用 // 。将单行注释放在续注释的语句上方。在注释之前放置一个空行,除非它位于代码块的第一行。

// 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;
}
Copy after login

所有注释符和注释内容用一个空格隔开,让它更容易阅读。

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;
}
Copy after login

给注释增加 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;
  }
}
Copy after login

使用 // TODO: 来标识需要实现的问题。注:如果代码中有该标识,说明在标识处有功能代码待编写,待实现的功能在说明中会简略说明。

class Calculator extends Abacus {
  constructor() {
    super();
    // TODO: total should be configurable by an options param
    this.total = 0;
  }
}
Copy after login

空格 Whitespace

使用 2 个空格作为缩进

// bad
function foo() {
∙∙∙∙let name;
}
// bad
function bar() {
∙let name;
}
// good
function baz() {
∙∙let name;
}
Copy after login

在大括号前放置 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',
});
Copy after login

在控制语句(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!');
}
Copy after login

使用空格把运算符隔开。

eslint: space-infix-ops jscs: requireSpaceBeforeBinaryOperators, requireSpaceAfterBinaryOperators

// bad
const x=y+5;
// good
const x = y + 5;
Copy after login

在文件末尾插入一个空行。

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;
Copy after login

长方法链式调用时使用缩进(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);
Copy after login

不要在圆括号内加空格。

// bad
function bar( foo ) {
  return foo;
}
// good
function bar(foo) {
  return foo;
}
// bad
if ( foo ) {
  console.log(foo);
}
// good
if (foo) {
  console.log(foo);
}
Copy after login

不要在中括号内添加空格。

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]);
Copy after login

在大括号内添加空格

// bad
const foo = {clark: 'kent'};
// good
const foo = { clark: 'kent' };
Copy after login

类型转换 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);
Copy after login

使数字: 使用 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);
Copy after login

布尔值:

eslint: no-new-wrappers

const age = 0;
// bad
const hasAge = new Boolean(age);
// good
const hasAge = Boolean(age);
// best
const hasAge = !!age;
Copy after login

命名规则 Naming Conventions

避免使用单字母名称。使你的命名具有描述性。

eslint: id-length

// bad
function q() {
// ...
}
// good
function query() {
// ...
}
Copy after login

当命名对象,函数和实例时使用驼峰式命名。

eslint: camelcase jscs: requireCamelCaseOrUpperCaseIdentifiers

// bad
const OBJEcttsssss = {};
const this_is_my_object = {};
function c() {}
// good
const thisIsMyObject = {};
function thisIsMyFunction() {}
Copy after login

当命名构造函数或类的时候使用 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',
});
Copy after login

当 导出(export) 一个默认函数时使用驼峰式命名。你的文件名应该和你的函数的名字一致。

function makeStyleGuide() {
// ...
}
export default makeStyleGuide;
Copy after login

当导出一个 构造函数 / 类 / 单例 / 函数库 / 纯对象时使用 PascalCase 式命名,(愚人码头注:即单词首字母大写)。

const AirbnbStyleGuide = {
  es6: {
    },
};
export default AirbnbStyleGuide;
Copy after login

存取器 Accessors

属性的存取器函数不是必须的。

別使用 JavaScript 的 getters/setters,因为它们会导致意想不到的副作用,而且很难测试,维护和理解。相反,如果要使用存取器函数,使用 getVal() 及 setVal(‘hello’)。

// bad
class Dragon {
  get age() {
    // ...
  }
  set age(value) {
    // ...
  }
}
// good
class Dragon {
  getAge() {
    // ...
  }
  setAge(value) {
    // ...
  }
}
Copy after login

如果属性/方法是一个 boolean, 使用 isVal() 或 hasVal() 方法。

// bad
if (!dragon.age()) {
  return false;
}
// good
if (!dragon.hasAge()) {
  return false;
}
)
Copy after login


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!

Related labels:
source:segmentfault.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!