# 快速导航

# 前言

您将在本篇中看完收获到

  • 换行与缩进
  • 空格约束
  • 常见开发实用技巧
编程规范

# 换行与缩进

每行语句的字符数不得超过 120 个英文字符,当一行的字符超过 120 行时,可以换行(这个不是硬性规定,一行语句太长了,就会影响阅读) 换行按照以下约束进行行缩进控制:函数参数换行。

换行后的第一个参数的首字母应该和函数第一个参数的首字母左对齐,如下所示

// 当有一些函数名称比较长的时候,多个参数,可以选择换行
function someLongNameMethod(longExpression1, longExpression2, longExpression3) {
  // 逻辑代码
}
1
2
3
4

表达式换行。操作符应该换行。如果表达式中含有"( )"运算符,则不应该换行。如下所示

合法:把有关联的放在一起

longName1 = longName2 * (longName3 + longName4 - longName5) + 4 * longname6;
1

非法

longName1 = longName2 * (longName3 + longName4
longName5) + 4 * longname6;
1
2

对于较长的需要换行的三重运算符" ? :",应该采用如下格式

nHeight = (x==y)
? alert( '弹出一表达式为真的提示' )
: alert( ''弹出表达式为假的提示");
1
2
3

"?"":"换行,且":""?"左对齐 以下情况,不应该使用缩进

针对整个 js 文件的注释的第一行及最后一行

/**
 * 函数功能详细
 * @param [参数1] [参数说明]
 * @param [参数2] [参数说明]
 * @return [返回值说明]
 */
1
2
3
4
5
6
  • 常量定义及其注释行
const LANGUAGE_KEY = 'language_key';
1
  • 全局变量定义及其注释行

  • 针对函数的注释的第⼀行以及最后一行

  • 每个函数结尾的"}"

  • 函数中的语句,每行的缩进数为 2 个空格

function getParentNode(node) {
  let oParentNode;
}
1
2
3

缩进应该使用空格符,严禁使用制表符进行缩进 因为在使用不同的文本编辑工具编写代码时,Tab 字符会由于用户设置的不同而调整为不同的宽度

# 空格约束

  • 元算术运算符和二元逻辑运算符的两侧必须且只能留出一个空格
var nWidth = 100;
x = y + z;
width = height / 2;
x += 1;
if (exp1 && exp2 && exp3 && exp4 == exp5) {
}
1
2
3
4
5
6
  • 三元运算符中,"?"":"两侧须留一个空格,如下
x = y == 0 ? 1 : 0;
1

一元运算符与变量或表达式之间不能留空格,如下所示

x = !y;
if(!exp1 && exp2)
1
2
  • 函数定义中,每个参数后面的","与下一个参数之间必须留出一个空格,第一个参数与"("之间不能有空格;最后⼀个参数与")"之间不能有空格
// 弹出模态框
function openModelDialog(url, winName, width, height) {
  // 逻辑代码
}
1
2
3
4
  • 函数定义中,函数名与其后面的"("之间不能留空格
function openModelDialog() {}
1
  • 函数定义中,")""{"之间必须留留一个空格
function openModelDialog() {}
1
  • 条件语句句、流程控制语句中,关键字与左括号"("之间不必须有空格;但右括号")"与"{"花括号之间必须有空格,如下所示
// if语句句:
if (true) {
  // 逻辑判断语句
} else {
  // 逻辑判断语句
}
// while语句句:
while (x != 0) {
  // 逻辑语句
}
// switch语句句:
switch (
  x
  // 逻辑语句
) {
}
// do..while语句句:
do {
  // 逻辑语句
} while (i == 0);
// for语句句:
for (i = 0; 10 >= i; i++) {
  // 逻辑语句
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
  • 键值对当中冒号与值之间要空格
var obj = { key: 'value' }; // ✗ avoid
var obj = { key: 'value' }; // ✗ avoid
var obj = { key: 'value' }; // ✗ avoid
var obj = { key: 'value' }; // ✓ ok
1
2
3
4
  • 行末不留空格

# 语句格式

每行定义一个变量,写一条语句,如下所示

const nWidth = 100;
const nHeight = 200;
const nWidth, nHeight; // ✗ avoid,不要写在一行,线上代码可以压缩成一行,但是本地代码应当换行的
x += 2; remove(this); // ✗ avoid,同上
1
2
3
4
  • 函数体的第⼀条语句与函数定义行之间不留空行
function openModelDialog() {
  x = y + 1;
}
1
2
3
  • 函数语句之间,应该根据实际情况进行空行,以增加代码的可读性
function openModelDialog() {
  let clickRow = setItem();
  if (clickRow) {
    clickRow.className = rowStyle;
  }
  let key = LASTCLICKITEM_KEY;
  let value = id;
}
1
2
3
4
5
6
7
8
  • 两个函数定义之间,必须空⼀行
function fun1() {}

function fun2() {}
1
2
3
  • 函数的返回语句与其他的语句之间须空⼀行
function openModelDialog() {
  x = y + 1;
  return true;
}
1
2
3
4
  • 函数定义中,左大括号"{"与右括号")"须位于同⼀行,中间留⼀个空格。右大括号"}"必须独占⼀行,并且与关键字"function"对⻬
function openModelDialog() {
  // ...
}
1
2
3

if 语句 格式如下

if (row === clickRow) {
  row.className = clickItemStyle;
  width = 100;
} else {
  row.className = rowStyle;
}
1
2
3
4
5
6

约束说明

  • ifelse中的语句缩进数为 2 个空格(相对于ifelse关键字)
  • 即使只有⼀条语句句,也必须用"{ }"括起来,禁止使用以下格式
if (row === clickRow)
  // 非法
  return;
1
2
3

switch 语句

switch (x) {
  case 1:
    语句;
    break;
  case 2:
    语句;
    break;
  default:
    语句;
    break;
}
1
2
3
4
5
6
7
8
9
10
11

约束说明

各个case关键字相对于switch的缩进数为 2 个空格 case中的语句相对于case关键字的缩进数为 2 个空格 必须有default分⽀

for 语句

for (i = 0; i <= 10; i++) {
   语句;
}
1
2
3

约束说明:

  • 循环判断中,分号";"与后面的表达式之间须留一个空格
  • 各语句相对于for的缩进数为 2 个空格
  • 即使for中只有一条语句,也必须用"{ }"双大括号括起来,禁止使用以下格式
// 非法
for (i = 0; i <= 10; i++) alert(i);
1
2

while 语句

while (i <= 10) {
  // 逻辑代码
}
1
2
3

约束说明

  • 各语句相对于 while 的缩进数为 2 个空格
  • 即使while中只有一条语句,也必须用"{ }"括起来,禁止使用以下格式

do while 语句

do {
   // 逻辑代码
} while10 >= i)
1
2
3

约束说明

  • 各语句相对于关键字 do 的缩进数为 2 个空格
  • 即使只有一条语句句,也必须用"{ }"括起来,禁止使用以下格式
do
   alert(i); // ⾮法
while10 >= i)
1
2
3

不允许有连续多行空行 如下是一个完整的例子

/*
 * @LineStart: -------------------------------------------
 * @Copyright: © 2020, itclanCoder. All rights reserved.
 * @LineEnd: ----------------------------------------------
 * @Product:
 * @Mode Name:
 * @Autor: vxPublic:itclanCoder
 * @Date: 2020-03-06 11:17:19
 * @Version: xxx.v1.0
 * @LastEditors: 川川
 * @LastEditTime: 2020-03-06 11:17:44
 * @Description: 完整的注释例子
 */

/* 声明最后一个列表的key */
const LASTCLICKITEM_KEY = 'lastClickItem';
/* 点击最后一个列表的样式风格 */
const g_sLastClickItemStyle = 'selectedRow';
/* 正常行的样式风格 */
const g_sNormalRowStyle = 'normalRow';
/* 鼠标经过行的样式风格 */
const g_sMouseoverRowStyle = 'mouseOverRow';
/**
 * 打开浏览器器新窗⼝。
 *
 * @param url 窗⼝URL。
 * @param winName 窗⼝名称。
 * @param width 窗⼝宽度。
 * @param height 窗⼝⾼高度。
 */
function openNewDialog(url, winName, width, height) {
  const nWidth = window.screen.width;
  const nHeight = window.screen.height;
  const sWinStr =
    'left=' +
    (swidth - width) / 2 +
    ',top=' +
    ((sheight - height) / 2 - 20) +
    ',width=' +
    width +
    ',height=' +
    height;
  // open a dialog
  const win = window.open(url, winName, `resizable=no,scrollbars=yes,${str}`);
  win.focus();
  return false;
}
/**
 * 打开模态窗⼝口。
 *
 * @param url 窗⼝URL。
 * @param winName 窗名称。
 * @param width 窗⼝宽度。
 * @param height 窗⼝⾼度。
 */
function openModelDialog(url, winName, width, height) {
  const nWidth = window.screen.width;
  const nHeight = window.screen.height;
  const winStr =
    'left=' +
    (swidth - width) / 2 +
    ',top=' +
    ((sheight - height) / 2 - 20) +
    ',width=' +
    width +
    ',height=' +
    height;
  // open a model dialog,打开模态对话框
  const win = window.showModalDialog(url, winName, str);
  win.focus();
  return false;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

# 常见开发技巧

Truefalse布尔表达式 下面的布尔表达式都返回false

  • null
  • undefined
  • "" // 空字符串
  • 0 // 数字 0

注意下面的返回true

  • '0' // 字符串 0
  • [] // 空数组
  • {} // 空对象
while (x != null) { // bad,如果你想判断变量x是不是为null空
   // 逻辑代码
}

while (x) {   // good (只要你希望 变量x 不是 0 和空字符串, 和 false)
  // 逻辑代码
}
if (y != null && y != '') { // bad
...
}

if (y) { // good (只要你希望 变量x 不是 0 和空符串, 和 false)
...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

也要注意下面的

Boolean('0') == true; // true
'0' != true; // true
0 != null; // true
0 == []; // true,比较的是值,如果是全等===,那么将是false
0 == false; // true
Boolean(null) == false; // true
null != true; // true
null != false; // true
Boolean(undefined) == false; // true
undefined != true; // true
undefined != false; // true
Boolean([]) == true; // true
Boolean({}) == true; // true
1
2
3
4
5
6
7
8
9
10
11
12
13

条件(三元)操作符 (?)

// 传统写法
if (val != 0) {
  return foo();
} else {
  return bar();
}
// 三元操作符写法
return val ? foo() : bar();
1
2
3
4
5
6
7
8
  • ?:与他们所负责的代码处于同⼀行 if..else表达式都可以转换为三元操作符,但是可读性没那么好, &&|| 二元布尔操作符是可以短路的, 只有在必要时才会计算到最后一项."||"被称作为 'default' 操作符, 因为可以这样
// 传统写法
if (node) {
  if (node.kids) {
    if (node.kids[index]) {
      foo(node.kids[index]);
    }
  }
}
// "&&"操作符代替写法
if (node && node.kids && node.kids[index]) {
  foo(node.kids[index]);
}
// 或者按如下写法:
var kid = node && node.kids && node.kids[index];
if (kid) {
  foo(kid);
}
// 下面这种写法就不要写成这样了的
node && node.kids && node.kids[index] && foo(node.kids[index]);

// 传统写法
function foo(opt_win) {
  let win;
  if (opt_win) {
    win = opt_win;
  } else {
    win = window;
  }
}

// "||"操作符代替写法
function foo(opt_win) {
  let win = opt_win || window;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

# 结语

篇主要介绍了 JS 中一些编程规范,涉及到换行与缩进-空格约束-语句格式,以及最后的常见开发技巧,表达式中真假,以及短路的处理

你或多或少都会看到一些类似这样的写法,Es6中也提供了设置默认参数,也是一种简化处理

如果强制自己写代码写的得更规范,可以用 eslint 等一些工具强制自己的

白色

关注公众号

一个走心,有温度的号,同千万同行一起交流学习

加作者微信

扫二维码 备注 【加群】

扫码易购

福利推荐