매력적인 코드 작성: 가독성, 유지 관리 및 성능 최적화의 핵심

이 글은 업무 개발에서 자주 접하는 비즈니스 로직의 우아한 글쓰기를 정리하고, 신입사원으로서 창업 방법을 몰랐을 때의 페인 포인트를 정리한 것입니다. 표준화되지 않았습니다.

글을 쓰고 난 후에도 여전히 기분이 좋고, 또 무언가를 배웠습니다.

텍스트의 시작

우아한 코드를 작성하는 이유는 무엇입니까?

간결한 구문과 구조를 채택하고, 일관된 명명 규칙을 따르고, 좋은 코드 구성과 주석을 갖고, 코드의 의도와 논리를 동시에 표현하세요.

주로 다음과 같은 이점이 있습니다.

  1. 가독성 : 읽기 쉽고 이해하기 쉽습니다. 명확한 이름 지정, 간결한 구문 및 좋은 코드 구조는 코드의 의도를 더 명확하게 만들고 降低理解代码的难度코드의 가독성을 향상시킬 수 있습니다.

  2. 유지 보수성 : 유지 보수가 용이합니다. 코드 논리가 명확하고 구조가 간결하면 개발자가 更快速地定位和修复bug기능을 확장하거나 수정할 수 있습니다. 동시에 읽기 쉬운 코드는 후속 코드 리팩토링 및 최적화에도 도움이 됩니다.

  3. 확장성 : 보다 확장 가능하고 유연합니다 灵活性. 명확한 코드 구조와 간결한 코딩 스타일을 통해 새로운 기능을 추가하거나 기존 기능을 수정하거나 코드를 확장하기가 더 쉽습니다. 또한 간결한 코드는 특정 구현 세부 사항에 덜 의존하는 경향이 있어 더 많은 유연성과 대체 가능성을 허용합니다.

  4. 오류 감소 및 디버깅 시간 : 更容易写出正确的逻辑,减少了出错的概率. 동시에 코드에 문제가 있을 때 우아하고 간결한 코드는 오류를 디버깅하고 찾기가 더 쉽습니다.

  5. 성능 최적화 : 간결한 코드는 일반적으로 더 효율적이며 불필요한 계산과 리소스 소비를 줄입니다. 간소화된 코드 구조 및 알고리즘은 코드 실행 효율성 및 성능을 향상시킬 수 있습니다.

기본 기술

1. 화살표 함수를 사용하여 함수 정의 단순화

// 传统函数定义
function add(a, b) {
 return a + b;
 }
  
 // 箭头函数简化
 const add = (a, b) => a + b;

2. 구조 분해 할당을 사용하여 변수 선언 단순화

// 传统变量声明
const firstName = person.firstName;
const lastName = person.lastName;
// 解构赋值简化
const { firstName, lastName } = person;

3. 템플릿 리터럴을 사용한 문자열 연결

// 传统字符串拼接
const greeting = 'Hello, ' + name + '!';
// 模板字面量简化
const greeting = `Hello, ${name}!`;

4. 배열 및 개체 작업에 스프레드 연산자 사용

// 合并数组
const combined = [...array1, ...array2];
// 复制对象
const clone = { ...original };

5. 배열의 고차 방법을 사용하여 루프 및 데이터 조작을 단순화합니다.

// 遍历数组并返回新数组
const doubled = numbers.map(num => num * 2);
// 过滤数组
const evens = numbers.filter(num => num % 2 === 0);

6. 조건 연산자를 사용하여 조건부 판단 단순화

// 传统条件判断
let message;
if (isSuccess) {
 message = 'Operation successful';
} else {
 message = 'Operation failed';
}
// 条件运算符简化
const message = isSuccess ? 'Operation successful' : 'Operation failed';

7. 객체 구조 분해 및 기본 인수로 함수 인수 단순화

// 传统参数设置默认值
function greet(name) {
 const finalName = name || 'Guest';
 console.log(`Hello, ${finalName}!`);
 }
  
 // 对象解构和默认参数简化
 function greet({ name = 'Guest' }) {
 console.log(`Hello, ${name}!`);
 }

8. 순수 함수 및 함수 구성과 같은 함수형 프로그래밍 개념 사용

// 纯函数
function add(a, b) {
 return a + b;
 }
  
 // 函数组合
 const multiplyByTwo = value => value * 2;
 const addFive = value => value + 5;
 const result = addFive(multiplyByTwo(3));

9. 객체 리터럴을 사용하여 객체 생성 및 정의 간소화

// 传统对象创建
const person = {
 firstName: 'John',
 lastName: 'Doe',
 age: 30,
 };
  
 // 对象字面量简化
 const firstName = 'John';
 const lastName = 'Doe';
 const age = 30;
 const person = { firstName, lastName, age };

10. 적절한 이름 지정 및 주석을 사용하여 코드 가독성 향상

// 不好的
const x = 10; // 设置x的值为10
function a(b) {
 return b * 2; // 返回b的两倍
}
// 好的
const speed = 10; // 设置速度为10
function double(value) {
 return value * 2; // 返回输入值的两倍

그런 다음 음악을 틀고 춤을 춥니다(실전 전투)! ! !

전투

1. 조건부 판단 코드를 우아하게 작성

간단한 조건판단논리 if else 나 삼항연산자, 무슨 말인지 한눈에 알 수 있지만 겹겹이 쌓인 수많은 if else삼항연산자는 수신자의 악몽~~~

삼항연산자 중첩 사례를 알려드릴께요 프로젝트에서 실제로 마주쳤는데 CPU가 직접 터졌습니다~~~

<view>{
   
   {status===1?'成功': status===2 ? '失败' : status===3 ? '进行中' : '未开始' }}</view>

아마도 이와 같이 특정 프로젝트 코드를 이해하는 한 여기에 넣기가 쉽지 않을 것입니다.

인간의 뇌의 논리와 일맥상통하고 가독성이 높으며 보기에도 편해 보이는 복잡한 논리는 오브젝트 맵 작성법을 사용하는 것을 추천합니다~~~

1. 그렇지 않으면 보통

let txt = '';
if (falg) {
 txt = 成功
} else {
 txt = 失败
}

2. 삼항 연산자

let txt = flag ? 成功 : 失败;

3. 그렇지 않으면 여러 번

// param {status} status 活动状态:1:成功 2:失败 3:进行中 4:未开始
let txt = '';
if (status == 1) {
 txt = 成功;
} else if (status == 2) {
 txt = 失败;
} else if (status == 3) {
 txt = 进行中;
} else {
 txt = 未开始;
}

4, 스위치 케이스

let txt = '';
switch (status) {
 case 1:
 txt = 成功;
 break;
 case 2:
 txt = 成功;
 break;
 case 3:
 txt = 进行中;
 break;
 default:
 txt = 未开始;
}

5. 객체 작성

const statusMap = {
 1: 成功,
 2: 失败,
 3: 进行中,
 4: 未开始
}
//调用直接 statusMapp[status]

6. 지도 작성 방법

const actions = new Map([
 [1, 成功],
 [2, 失败],
 [3, 进行中],
 [4, 未开始]
])
// 调用直接 actions.get(status)

2. 조건문 캡슐화

위와 같이 if에 조건이 많을수록 수신자의 유지에 불리하고 인간의 뇌의 이해에 도움이 되지 않는 언뜻 논리의 무리이다. 여러 논리적이어야 합니다 化零为整.

大脑:'别来碰我,让我静静'

// 不好的
if (fsm.state === 'fetching' && isEmpty(listNode)) {
 // ...
}
// 好的
shouldShowSpinner(fsm, listNode){
 return fsm.state === 'fetching' && isEmpty(listNode)
}
if(shouldShowSpinner(fsm, listNode)){
 //...doSomething
}

3. 함수는 한 가지 일만 해야 합니다.

기능적 작성 방법은 높이 평가되며 柯里化하나의 기능과 하나의 기능으로 분할 및 조립이 가능합니다.

// 不好的
function createFile(name, temp) {
 if (temp) {
   fs.create(`./temp/${name}`);
 } else {
   fs.create(name);
 }
}
// 好的
function createFile(name) {
 fs.create(name);
}
function createTempFile(name) {
 createFile(`./temp/${name}`)
}

밤 하나 더

함수가 하는 일은 다음과 같습니다.

  • 클라이언트 어레이 통과

  • 순회 프로세스 중에 조회 기능을 통해 새 개체 clientRecord를 얻습니다.

  • clientRecord 객체 의 isActive 함수가 true를 반환 하는지 확인합니다 .

    • isActive 함수는 true 를 반환하고 이메일 함수를 실행하며 현재 구성원을 가져옵니다.

// 不好的
function emailClients(clients) {
 clients.forEach((client) => {
   const clientRecord = database.lookup(client);
   if (clientRecord.isActive()) {
     email(client);
   }
 });
}
// 好的
function emailClients(clients) {
 clients
   .filter(isClientRecord)
   .forEach(email)
}
function isClientRecord(client) {
 const clientRecord = database.lookup(client);
 return clientRecord.isActive()
}

위의 나쁜 밤은 언뜻보고 코드가 잔뜩있는 것 같은 느낌이 들고 한동안보고 싶지도 않습니다.

좋은 밤, 논리가 명확하고 읽기 쉽지 않습니까?

  • 필터 기능을 능숙하게 사용하여 조건부 처리 필터의 콜백 함수를 열고 조건에 맞는 데이터를 반환

  • forEach를 능숙하게 사용하여 검증된 데이터에 대한 이메일 기능 실행

4. Object.assign은 기본 개체에 기본값을 할당합니다.

// 不好的
const menuConfig = {
 title: null,
 body: 'Bar',
 buttonText: null,
 cancellable: true
};
function createMenu(config) {
 config.title = config.title || 'Foo';
 config.body = config.body || 'Bar';
 config.buttonText = config.buttonText || 'Baz';
 config.cancellable = config.cancellable === undefined ?
 config.cancellable : true;
}
createMenu(menuConfig);
// 好的
const menuConfig = {
 title: 'Order',
 buttonText: 'Send',
 cancellable: true
};
function createMenu(config) {
 Object.assign({
   title: 'Foo',
   body: 'Bar',
   buttonText: 'Baz',
   cancellable: true 
 }, config)
}
createMenu(menuConfig);

5. 함수 매개변수는 2개 미만이 가장 좋습니다.

천 단어와 만 단어를 말하는 것은 우아함과 좋은 가독성을 위한 것입니다.

// 不好的
function createMenu(title, body, buttonText, cancellable) {
 // ...
}
// 好的
const menuConfig = {
 title: 'Foo',
 body: 'Bar',
 buttonText: 'Baz',
 cancellable: true
};
function createMenu(config){
 // ...
}
createMenu(menuConfig)

6. 설명 변수 사용

흐름을 저장하고 가독성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;

7. 클로저를 통해 개체에 전용 멤버를 지정합니다.

폐쇄는 본질적으로 사유화됩니다.

// 不好的
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

첫 번째 예

이점:

  • 메모리 공간을 절약 함으로써 原型链共享方法. getName 모든 인스턴스 개체는 각 인스턴스 개체에 대해 독립적인 메서드를 만드는 대신 동일한 메서드를 공유합니다  .

결점:

  • 생성자에서 직접 개인 속성이나 메서드를 정의할 수 있는 방법은 없습니다 所有属性和方法都会被暴露在原型链上.

두 번째 예

이점:

  • 생성자 내부에 있을 수 있으며 定义私有属性和方法개체의 프로토타입 체인에 노출되지 않으므로 더 나은 캡슐화를 제공합니다.

결점:

  • 인스턴스 개체가 생성될 때마다 독립적인 메서드, 每个实例对象都有자체  getName 메서드가 더 많은 메모리 공간을 차지합니다.

8. 메서드 체이닝 사용

链式写法코드 우아함의 하이라이트이기도 합니다.

추신: 이것을 발명한 프로그래머는 백엔드에서 왔을 것입니다.이런 글은 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();

위의 많은 밤을 읽은 후 친구의 생각이 훨씬 더 명확해졌습니다. 프로젝트에서 연습합시다.

당신이 얻게 될 것은 동료와 수신자의 감사와 마음의 위안입니다! ! !

나는 이 기사에 내 메모와 아이디어를 여기에 넣기 위해 최선을 다했습니다. 친구들에게 도움이 되기를 바랍니다.

재인쇄는 환영하지만 출처를 밝혀주세요.

마지막으로 친구들이 저에게 무료 좋아요를 해주기를 바라며 모든 소원이 이루어지고 평화와 기쁨이 있기를 바랍니다.

Supongo que te gusta

Origin blog.csdn.net/qq_48652579/article/details/131364132
Recomendado
Clasificación