再温习一下 Github 上 star 有 90k 的 Javascript 代码风格指南。基本所有内容都来自 仓库,也可以直接查看原文。
变量
-
使用意义明确的变量名
Use meaningful and pronounceable variable names
// Bad const yyyymmdstr = moment().format("YYYY/MM/DD"); // Good const currentDate = moment().format("YYYY/MM/DD"); -
对于相同/类似类型的变量应该用一个统一的变量名进行命名
Use the same vocabulary for the same type of variable
// Bad getUserInfo(); getClientData(); getCustomerRecord(); // Good getUser(); -
使用可搜索的变量命名
Use searchable names
// Bad setTimeout(blastOff, 86400000); // Good const MILLISECONDS_PER_DAY = 60 * 60 * 24 * 1000; //86400000; setTimeout(blastOff, MILLISECONDS_PER_DAY); -
使用可解释的变量命名,尽量减少匿名函数使用
Use explanatory variables
// Bad const address = "One Infinite Loop, Cupertino 95014"; const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/; saveCityZipCode( address.match(cityZipCodeRegex)[1], address.match(cityZipCodeRegex)[2] ); // Good const address = "One Infinite Loop, Cupertino 95014"; const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/; const [_, city, zipCode] = address.match(cityZipCodeRegex) || []; saveCityZipCode(city, zipCode); -
减少「个人心智」的映射,(减少意义模糊的变量命名映射)感觉和第一点其实是一致的
Avoid Mental Mapping
// Bad const locations = ["Austin", "New York", "San Francisco"]; locations.forEach(l => { doStuff(); doSomeOtherStuff(); // ... // l 代表什么?意义模糊 dispatch(l); }); // Good const locations = ["Austin", "New York", "San Francisco"]; locations.forEach(location => { doStuff(); doSomeOtherStuff(); // ... dispatch(location); }); -
减少冗余的命名方式
Don't add unneeded context
// Bad const Car = { carMake: "Honda", carModel: "Accord", carColor: "Blue" }; function paintCar(car, color) { car.carColor = color; } // Good const Car = { make: "Honda", model: "Accord", color: "Blue" }; function paintCar(car, color) { car.color = color; } -
使用参数默认值的方式取代「短路方式」的条件判断赋值
Use default parameters instead of short circuiting or conditionals
// Bad function createMicrobrewery(name) { const breweryName = name || "Hipster Brew Co."; // ... } // Good function createMicrobrewery(name = "Hipster Brew Co.") { // ... }
函数
-
函数的参数数量尽量在2个或者2个以下,如果必须使用超过3个以上的参数,可以使用对象来代替,对于es6来说,可以使用对象解构的方式声明函数的参数
Function arguments (2 or fewer ideally)
// Bad function createMenu(title, body, buttonText, cancellable) { // ... } createMenu("Foo", "Bar", "Baz", true); // Good function createMenu({ title, body, buttonText, cancellable }) { // ... } -
一个函数应该只做一件事情,保持函数的单一性
Functions should do one thing
// Bad function emailClients(clients) { clients.forEach(client => { const clientRecord = database.lookup(client); if (clientRecord.isActive()) { email(client); } }); } // Good function emailActiveClients(clients) { clients.filter(isActiveClient).forEach(email); } function isActiveClient(client) { const clientRecord = database.lookup(client); return clientRecord.isActive(); } -
函数的名称应该说明了这个函数的作用,即要有明确的变量意义
Function names should say what they do
function addToDate(date, month) { // ... } const date = new Date(); // Bad function name addToDate(date, 1); // Good function name addMonthToDate(1, date); -
一个函数内应该只有一层抽象,(如何理解「只有一层抽象」?即不应该还有其他逻辑可以被抽取成单独的函数。这一点其实和一个函数只做一件事有点类型。
Functions should only be one level of abstraction
// Bad function parseBetterJSAlternative(code) { const REGEXES = [ // ... ]; const statements = code.split(" "); const tokens = []; REGEXES.forEach(REGEX => { statements.forEach(statement => { // ... }); }); const ast = []; tokens.forEach(token => { // lex... }); ast.forEach(node => { // parse... }); } // Good。可以拆分出不同的函数逻辑 function parseBetterJSAlternative(code) { const tokens = tokenize(code); const syntaxTree = parse(tokens); syntaxTree.forEach(node => { // parse... }); } function tokenize(code) { const REGEXES = [ // ... ]; const statements = code.split(" "); const tokens = []; REGEXES.forEach(REGEX => { statements.forEach(statement => { tokens.push(/* ... */); }); }); return tokens; } function parse(tokens) { const syntaxTree = []; tokens.forEach(token => { syntaxTree.push(/* ... */); }); return syntaxTree; } -
减少重复代码,尽量减少重复逻辑的代码
Remove duplicate code
// Bad 可以看出两个函数有重复的代码 function showDeveloperList(developers) { developers.forEach(developer => { const expectedSalary = developer.calculateExpectedSalary(); const experience = developer.getExperience(); const githubLink = developer.getGithubLink(); const data = { expectedSalary, experience, githubLink }; render(data); }); } function showManagerList(managers) { managers.forEach(manager => { const expectedSalary = manager.calculateExpectedSalary(); const experience = manager.getExperience(); const portfolio = manager.getMBAProjects(); const data = { expectedSalary, experience, portfolio }; render(data); }); } // Good。利用switch优化代码 function showEmployeeList(employees) { employees.forEach(employee => { const expectedSalary = employee.calculateExpectedSalary(); const experience = employee.getExperience(); const data = { expectedSalary, experience }; switch (employee.type) { case "manager": data.portfolio = employee.getMBAProjects(); break; case "developer": data.githubLink = employee.getGithubLink(); break; } render(data); }); }未完待续...