JavaScript 社区存在多种代码风格,从缩进到分号,从引号到逗号,每个选择都有支持者。本文将客观对比常见风格,帮助团队做出选择。
缩进风格
Tab vs 空格
// Tab 缩进
function greet(name) {
→ return 'Hello, ' + name;
}
// 空格缩进(4 空格)
function greet(name) {
return 'Hello, ' + name;
}
| 方面 | Tab | 空格 |
|---|---|---|
| 文件大小 | 更小 | 稍大 |
| 跨编辑器一致性 | 取决于设置 | 始终一致 |
| 可访问性 | 可自定义宽度 | 固定宽度 |
| 社区主流 | 少数 | 多数 |
建议:选择空格,因为跨平台一致性更重要。
2 空格 vs 4 空格
// 2 空格(React/Vue 社区主流)
function greet(name) {
return 'Hello, ' + name;
}
// 4 空格(传统 JS 社区主流)
function greet(name) {
return 'Hello, ' + name;
}
| 方面 | 2 空格 | 4 空格 |
|---|---|---|
| 横向空间 | 更多代码可见 | 较少代码可见 |
| 嵌套清晰度 | 稍弱 | 更强 |
| 流行框架 | React, Vue, Angular | jQuery, Node.js |
建议:跟随团队或项目的主流选择。
引号风格
单引号 vs 双引号
// 单引号
const name = 'test';
const html = '<div class="box">content</div>';
// 双引号
const name = "test";
const html = "<div class=\"box\">content</div>";
| 方面 | 单引号 | 双引号 |
|---|---|---|
| 输入便利性 | 不需要 Shift | 需要 Shift |
| HTML 内嵌 | 不需要转义 | 需要转义 |
| JSON 兼容性 | 需要转换 | 原生支持 |
| 社区主流 | JS 社区 | JSON/HTML |
建议:JS 代码用单引号,JSON 用双引号(规范要求)。
分号使用
有分号 vs 无分号
// 有分号
const name = 'test';
function greet() {
return 'hello';
}
// 无分号(Standard 风格)
const name = 'test'
function greet() {
return 'hello'
}
ASI(自动分号插入)陷阱:
// 危险代码
const a = 1
const b = 2
[a, b].forEach(console.log) // 报错!
// 解释为:
const b = 2[a, b].forEach(console.log)
// 2[2, 1] 是 undefined,undefined.forEach 报错
// 修复:无分号风格需要在行首加 ;
;[a, b].forEach(console.log)
| 方面 | 有分号 | 无分号 |
|---|---|---|
| 安全性 | 无 ASI 问题 | 需要注意陷阱 |
| 代码简洁 | 多一个字符 | 更简洁 |
| 社区主流 | 多数项目 | Standard/Vue |
建议:使用分号,避免潜在的 ASI 问题。
大括号风格
K&R vs Allman
// K&R(同行)
if (condition) {
doSomething();
} else {
doOther();
}
// Allman(换行)
if (condition)
{
doSomething();
}
else
{
doOther();
}
| 方面 | K&R | Allman |
|---|---|---|
| 行数 | 更少 | 更多 |
| 可读性 | 紧凑 | 清晰 |
| JS 社区 | 主流 | 少数 |
| C#/C++ | 少数 | 主流 |
建议:JS 使用 K&R 风格,这是社区惯例。
尾逗号
有尾逗号 vs 无尾逗号
// 有尾逗号
const obj = {
name: 'test',
age: 18,
};
const arr = [
1,
2,
3,
];
// 无尾逗号
const obj = {
name: 'test',
age: 18
};
| 方面 | 有尾逗号 | 无尾逗号 |
|---|---|---|
| Git diff | 更清晰 | 多一行改动 |
| 添加新项 | 方便 | 需要修改上一行 |
| 兼容性 | ES5+ | 所有环境 |
建议:使用尾逗号(es5 模式),Git diff 更友好。
箭头函数
单行 vs 多行
// 单行(隐式返回)
const double = x => x * 2;
const sum = (a, b) => a + b;
// 多行(显式返回)
const process = (data) => {
const filtered = data.filter(x => x > 0);
return filtered.map(x => x * 2);
};
建议:
- 简单逻辑用单行箭头函数
- 超过 3 行用多行形式
命名风格
变量和函数
// camelCase(主流)
const userName = 'test';
function getData() { }
// snake_case(少数)
const user_name = 'test';
function get_data() { }
// PascalCase(类/组件)
class UserService { }
function UserProfile() { }
建议:变量/函数用 camelCase,类/组件用 PascalCase。
导入顺序
// 推荐:分组排序
// 1. Node.js 内置模块
import fs from 'fs';
import path from 'path';
// 2. 第三方库
import React from 'react';
import axios from 'axios';
// 3. 内部模块(别名路径)
import { API_URL } from '@/config';
import UserService from '@/services/UserService';
// 4. 相对路径
import { formatDate } from './utils';
import styles from './App.module.css';
// 5. 样式文件
import './global.css';
注释风格
// 单行注释
const value = 42; // 魔法数字
// 多行注释
/*
* 这是一个复杂的算法
* 用于处理特殊情况
*/
function complexAlgorithm() { }
// JSDoc
/**
* 获取用户信息
* @param {string} id - 用户 ID
* @returns {Promise<User>} 用户信息
*/
async function getUser(id) { }
// TODO/FIXME
// TODO: 添加错误处理
// FIXME: 在 Safari 下有兼容性问题
风格配置推荐
Prettier 配置
{
"semi": true,
"singleQuote": true,
"tabWidth": 4,
"trailingComma": "es5",
"printWidth": 100,
"bracketSpacing": true,
"arrowParens": "avoid"
}
ESLint 配置
{
"extends": [
"eslint:recommended",
"prettier"
],
"rules": {
"no-var": "error",
"prefer-const": "error",
"eqeqeq": ["error", "always"],
"curly": ["error", "multi-line"]
}
}
总结
代码风格没有绝对的对错,但团队统一很重要。选择一个主流风格,使用工具自动化,让开发者专注于逻辑而非格式。