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
calculateTotalPricefunction 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
reduceinstead 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
calculateTotalPricefunction 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, andreduceprovide 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.assignor Spread for Default Options - Before refactoring: Object.assign给默认对象赋默认值
- After refactoring:
- Explanation: Using
Object.assignor 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
thisin 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
afor 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…