Code Standard
icon
password
Extracting Functions
- Before refactoring:
- After refactoring:
- Explanation: Extracting the calculation of an item's total price into its own function makes the
calculateTotalPrice
function simpler and promotes code reuse.
- 重构代码最常见的技术之一是提取函数。这涉及获取一段执行特定任务的代码并将其移至其自己的函数中。这可以使代码更具可读性和可重用性。
Removing Duplicate Code
- Before refactoring:
- After refactoring:
- Explanation: Centralizing the duplicate code for calculating an item's total price into a single function reduces redundancy and improves maintainability.
- 删除重复代码。这涉及识别执行相同任务的代码段并将它们合并到单个函数中。
Renaming Variables and Functions
- Before refactoring:
- After refactoring:
- Explanation: Renaming functions and variables to more descriptive names makes the code easier to read and understand.
- 重命名变量和函数是重构代码的另一种技术。这涉及更改变量和函数的名称,以使它们更具描述性且更易于理解。
Simplifying Conditional Expressions
- Before refactoring:
- After refactoring:
- Explanation: Simplifying conditional expressions by removing unnecessary if statements makes the code more concise and easier to understand.
- 简化条件表达式是重构代码的另一种技术。这涉及重写条件表达式以使其更易于阅读和理解。
Replacing Loops with Functional Programming Constructs
- Before refactoring:
- After refactoring:
- Explanation: Using functional programming constructs like
reduce
instead of loops can make the code shorter and clearer.
- 用函数式编程结构替换循环是重构代码的另一种技术。这涉及使用map、filter和reduce等函数对数组执行操作,而不是使用循环。
- Encapsulating Conditionals
- Before refactoring:
- After refactoring:
- Explanation: Moving the conditional logic to determine discount eligibility into its own function makes the
calculateTotalPrice
function simpler and the logic more reusable.
- 封装条件是一种重构代码的技术,涉及将复杂的条件逻辑移至其自己的函数中。这可以使代码更易于阅读和理解。
- Replacing Temp with Query
- Before refactoring:
- After refactoring:
- Explanation: Replacing temporary variables with queries (function calls) makes the code more declarative and eliminates the need for intermediate variables.
- 用查询替换 temp 是一种重构代码的技术,涉及用函数调用替换临时变量。这可以使代码更具可读性并减少需要跟踪的变量数量。
- Using Arrow Functions to Simplify Function Definition 使用箭头函数简化函数定义
- Before refactoring:
- After refactoring:
- Explanation: Arrow functions provide a concise syntax for writing functions, making the code more readable and expressive.
- Using Destructuring Assignment to Simplify Variable Declarations 使用解构赋值简化变量声明
- Before refactoring:
- After refactoring:
- Explanation: Destructuring allows for unpacking values from arrays or properties from objects into distinct variables, reducing repetition and improving readability.
- Using Template Literals for String Concatenation 使用模板字面量进行字符串拼接
- Before refactoring:
- After refactoring:
- Explanation: Template literals provide an easier way to create strings with embedded expressions, improving clarity and readability.
- Using Spread Operator for Array and Object Manipulation 使用展开运算符进行数组和对象操作
- Before refactoring (Array Concatenation):
- After refactoring (Array Concatenation):
- Before refactoring (Object Cloning):
- After refactoring (Object Cloning):
- Explanation: The spread operator simplifies the process of concatenating arrays and cloning objects, making the code more concise and readable.
- Using High-order Array Methods for Loops and Data Operations 使用数组的高阶方法简化循环和数据操作
- Before refactoring:
- After refactoring:
- Explanation: High-order array methods like
map
,filter
, andreduce
provide a declarative approach to performing operations on arrays, making the code cleaner and easier to understand.
- Using Ternary Operator for Simplified Conditional Expressions 使用条件运算符简化条件判断
- Before refactoring:
- After refactoring:
- Explanation: The ternary operator allows for a more concise expression of simple conditional logic, reducing the need for verbose if-else statements.
- Using Object and Array Destructuring with Default Parameters to Simplify Function Parameters 使用对象解构和默认参数简化函数参数
- Before refactoring:
- After refactoring:
- Explanation: Using destructuring and default parameters simplifies function signatures and provides default values more declaratively.
- Applying Functional Programming Concepts like Pure Functions and Function Composition 使用函数式编程概念如纯函数和函数组合
- Pure Function Example (Before and After):
- Function Composition:
- Explanation: Pure functions and function composition promote code clarity, reusability, and testability by ensuring functions perform a single task and can be combined in flexible ways.
- Using Object Literals to Simplify Object Creation and Definition 使用对象字面量简化对象的创建和定义
- Before refactoring:
- After refactoring:
- Explanation: When the variable names and object property names are the same, you can use object literal shorthand notation to simplify object creation.
- Improving Code Readability with Proper Naming and Commenting 使用适当的命名和注释来提高代码可读性
- Before refactoring:
- After refactoring:
- Explanation: Using descriptive names for variables and functions, along with meaningful comments, significantly improves the readability and maintainability of code.
- Refactoring Conditional Logic for Clarity 优雅的写条件判断代码
- Object Mapping instead of Multiple if-else or Switch-case:
- Explanation: Using object maps for conditional logic can make the code more readable and easier to manage, especially when dealing with multiple conditional branches.
- Encapsulating Conditionals 封装条件语句
- Before refactoring:
- After refactoring:
- Explanation: Encapsulating complex conditional logic into its own function makes the conditions easier to read and reuse.
- Ensuring Functions Do One Thing 函数应该只做一件事
函数式写法推崇
柯里化
, 一个函数一个功能,可拆分可组装。 - Before refactoring:
- After refactoring:
- Explanation: Dividing the function into smaller, single-purpose functions improves readability, testability, and maintainability of the code.
- Using
Object.assign
or Spread for Default Options - Before refactoring: Object.assign给默认对象赋默认值
- After refactoring:
- Explanation: Using
Object.assign
or the spread operator to merge objects simplifies the process of applying default values to function parameters or configurations. - Limiting Function Parameters 函数参数两个以下最好
- Before refactoring:
- After refactoring:
- Explanation: Using an object as a function parameter allows you to pass multiple options as a single argument. This approach makes function signatures more manageable and improves readability, especially when dealing with many parameters.
- Using Descriptive Variables for Clarity 使用解释性的变量
- Before refactoring:
- After refactoring:
- Method Chaining for Fluent Interfaces
- Before refactoring:
- After refactoring:
- Explanation: Method chaining allows for a more fluent and readable way of expressing sequences of operations. By returning
this
in each method, you can chain methods together, making the code more concise and expressive. - Encapsulating Complex Conditionals 使用方法链
链式写法
也是代码优雅之道的重头戏。 - Before refactoring:
- After refactoring:
- Explanation: Moving complex conditional checks into a named function not only makes the code easier to read but also provides a single place to update the logic if needed, enhancing maintainability.
- 通过
原型链共享方法
,节省了内存空间。所有实例对象共享同一个getName
方法,而不是每个实例对象都创建一个独立的方法。 - 在构造函数中无法直接定义私有属性或方法,
所有属性和方法都会被暴露在原型链上
。 - 可以在构造函数内部
定义私有属性和方法
,不会暴露在对象的原型链上,提供了更好的封装性。 - 每次创建实例对象时,都会创建一个独立的方法,
每个实例对象都有
自己的getName
方法,占用更多的内存空间。 - "Good" (ironically, actually bad) way:
- Bad (actually good) way:
- Explanation: Descriptive naming improves code readability and maintainability. Using names like
a
for variables is confusing and not recommended. - "Good" way:
- Bad (actually good) way:
- Explanation: Consistent naming conventions enhance code clarity. Mixing styles, as in the "good" example, is poor practice and should be avoided.
- "Good" way:
- Bad (actually good) way:
- Explanation: Comments enhance understanding and maintainability, especially for complex logic or important decisions. Lack of comments can lead to confusion.
- "Good" way:
- Bad (actually good) way:
- Explanation: Comments should be accessible and understandable to all team members, using a common language.
- "Good" way:
- Bad (actually good) way:
- Explanation: While compact code can seem clever, readability and maintainability are more important. Break down complex operations for clarity.
- "Good" way:
- Bad (actually good) way:
- Explanation: Proper error handling is crucial for robust applications. Ignoring errors can lead to difficult-to-debug issues.
- "Good" way:
- Bad (actually good) way:
- Explanation: Global variables can lead to code that's hard to debug and maintain. Using function parameters and return values is a better practice.
- "Good" way:
- Bad (actually good) way:
- Explanation: Declaring variables that are never used can lead to cluttered and confusing code. Define only what is necessary.
- "Good" way:
- Bad (actually good) way:
- Explanation: Type definitions enhance code clarity and error prevention, especially in TypeScript. Skipping them can lead to unexpected behaviors.
- "Good" way:
- Bad (actually good) way:
- Explanation: Unreachable code indicates logic errors and should be removed for cleaner, more maintainable code.
- "Good" way:
- Bad (actually good) way:
- Explanation: Deep nesting makes code harder to read and maintain. Flattening logic by exiting early or using asynchronous patterns improves clarity.
- "Good" way:
- Bad (actually good) way:
- Explanation: Consistent indentation is key to code readability. Inconsistent or minimal indentation, as shown in the "good" example, can make code difficult to follow.
- Explanation: Using destructuring and descriptive variable names makes the code more readable and easier to understand, especially when working with complex expressions or data structures.
complex
16. 使用解释性的变量
省流,用了扩展运算符,为了可读性(
saveCityZipCode(city, zipCode)
可读性很好,知道参数是干嘛的)// 不好的
const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
saveCityZipCode(address.match(cityZipCodeRegex)[1], address.match(cityZipCodeRegex)[2]);
// 好的
const address = 'One Infinite Loop, Cupertino 95014';
const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
cosnt [, city, zipCode] = address.match(cityZipCodeRegex) || [];
saveCityZipCode(city, zipCode)
想对类中的属性进行更多自定义取/增/改的操作时,使用set/get
第一次见这个写法,不知道是啥意思的小伙伴,把他当成vue2中的defineProperty
Object.defineProperty(data1,'age',{
set:function(newAge){
console.log(this.name+'现在'+newAge+'岁')
},
get:function(){
return 18;
}
})
是一个意思,赋值的时候set会被触发,取值的时候get会被触发。
巧用自带属性,提升性能。
class BankAccount {
constructor(balance = 1000) {
this._balance = balance;
}
// It doesn't have to be prefixed with `get` or `set` to be a
//getter/setter
set balance(amount) {
console.log('set')
if (verifyIfAmountCanBeSetted(amount)) {
this._balance = amount;
}
}
get balance() {
console.log('get')
return this._balance;
}
verifyIfAmountCanBeSetted(val) {
// ...
}
}
const bankAccount = new BankAccount();
// Buy shoes...
bankAccount.balance -= 100;
// Get balance
let balance = bankAccount.balance;
17. 让对象拥有私有成员-通过闭包来实现
闭包天生就是做私有化的
// 不好的
const Employee = function(name) {
this.name = name;
};
Employee.prototype.getName = function getName() {
return this.name;
};
const employee = new Employee('John Doe');
console.log(`Employee name: ${employee.getName()}`); // Employee name: John Doe
delete employee.name;
console.log(`Employee name: ${employee.getName()}`); // Employee name: undefined
// 好的
const Employee = function(name){
this.getName = function(){
return name
}
}
const employee = new Employee('John Doe');
console.log(`Employee name: ${employee.getName()}`); // Employee name: John Doe
delete employee.name;
console.log(`Employee name: ${employee.getName()}`); // Employee name: undefined
第一个示例
优点:
缺点:
第二个示例
优点:
缺点:
18. 使用方法链
链式写法
也是代码优雅之道的重头戏。ps:发明这个的程序员肯定是后端出身的,这种写法在PHP的CI框架中见过。
// 不好的
class Car {
constructor() {
this.make = 'Honda';
this.model = 'Accord';
this.color = 'white';
}
setMake(make) {
this.make = make;
}
save() {
console.log(this.make, this.model, this.color);
}
}
const car = new Car();
car.setMake('Ford');
car.save();
// 好的
class Car {
constructor() {
this.make = 'Honda';
this.model = 'Accord';
this.color = 'white';
}
setMake(make) {
this.make = make;
// NOTE: return this是为了用链式写法
return this;
}
save() {
console.log(this.make, this.model, this.color);
// NOTE:return this是为了用链式写法
return this;
}
}
const car = new Car()
.setMake('Ford')
.save();
Rule 1: Naming Variables in a Confusing Manner
Rule 2: Mixing Naming Conventions
Rule 3: Avoid Writing Comments
Rule 4: Comments in a Non-native Language
Rule 5: Writing Code in a Single Line
Rule 6: Ignoring Error Handling
Rule 7: Extensive Use of Global Variables
Rule 8: Creating Unused Variables
Rule 9: Optionally Skipping Type Definitions (TS Example)
Rule 10: Writing Unreachable Code
Rule 11: Deeply Nested Logic (Pyramid of Doom)
Rule 12: Inconsistent Indentation
Last update: 2024-03-06
icon
password
I am currently in Melbourne
I am Looking for a Data Analytics Role…