-
Javascript Clean Code에 관하여Javascript 2021. 4. 11. 18:50
자바스크립트 클린코드에 대한 관점들이 많이 있습니다.
다른사람들을 위한 코드를 작성하는 것이 좋고, 또 그 자체로도 본인에게도 매우 도움이 되기 때문에 어떻게 보면, 클린코드는 좋은 개발자의 덕목에 필수불가결하다고 할 수 있습니다.
여전히 어지럽고 난해한 코드를 작성하는 법, 아무도 알아보지 못하게 코드를 작성하는 법에 대한 책들이 있긴 하지만, 저는 그런 관점에 대해서는 자기 자신이 자신이 없기 때문이라는 생각만 듭니다.
이 글에서는 자바스크립트 관점에서만 다룹니다.
1. 강력한 타입 체크
== 대신에 ===를 사용하세요.
0 == false // true 0 === false // false 2 == "2" // true 2 === "2" // false // 예시 const val = "123"; if (val === 123) { console.log(val); // 콘솔이 찍히지 않습니다. } if (val === "123") { console.log(val); // 콘솔이 찍힙니다. }
2. 변수 이름
변수 이름을 잘 지으세요.
BAD
let daysSLV = 10; let y = new Date().getFullYear(); let ok; if (user.age > 30) { ok = true; }
GOOD
const MAX_AGE = 30; let daysSinceLastVisit = 10; let currentYear = new Date().getFullYear(); ... const isUserOlderThanAllowed = user.age > MAX_AGE;
조금 길어지더라도 자세하게 내용을 적어주는 것이 다른사람들이 보기에 더 이해가 쉬울 것입니다.
하지만, 불필요한 단어는 피해야합니다.
BAD
let nameValue; let theProduct;
GOOD
let name; let product;
문맥을 외워야하도록 만들지 마세요.
BAD
const products = ["T-Shirt", "Shoes", "Watches", "Bags"]; products.forEach(p => { doSomething(); doSomethingElse(); . . . // p가 뭐야? register(p); });
GOOD
const products = ["T-Shirt", "Shoes", "Watches", "Bags"]; products.forEach(product => { doSomething(); doSomethingElse(); . . . register(product); });
문맥을 불필요하게 추가하지마세요.
BAD
const product = { productId: 1, productName: "T-Shirt", productPrice: 8.99, productUnits: 12 }; ... product.productName;
불필요하게 product가 prefix로 모두 들어간 모습입니다.
GOOD
const product = { id: 1, name: "T-Shirt", price: 8.99, units: 12 }; ... product.name;
동일한 유형의 변수에 동일한 어휘 사용하기
BAD
getUserInfo(); getClientData(); getCustomerRecord();
GOOD
getProduct();
3. 함수
길고 설명이 충분히 되는 함수이름을 사용하세요.
특정 동작을 나타내는 것을 고려할 때 함수 이름은 인수의 의도뿐만 아니라 그 뒤에있는 의도를 완전히 드러내는 동사 또는 구문이어야합니다.
BAD
function email(user) { // 실행 }
GOOD
function sendEmailUser(emailAddress) { // 실행 }
긴 인수를 피하세요.
인수가 적을수록 함수를 테스트하기가 더 쉽습니다.
BAD
function getProducts(fields, fromDate, toDate) { // 실행 }
GOOD
function getProducts({ fields, fromDate, toDate }) { // 실행 } getProducts({ fields: ['id', 'name', 'price', 'units], fromDate: '2020-07-01', toDate: '2020-07-22' });
브라우저 지원 여부에 따라 조건 인수 대신에 기본 타입 인수를 사용하세요.
BAD
function createShape(type) { const shapeType = type || "circle"; // ... }
GOOD
function createShape(type = "circle") { // ... }
단일 기능 내에서 여러 작업 실행 하지 마세요.
BAD
function notifyUsers(users) { users.forEach(user => { const userRecord = database.lookup(user); if (userRecord.isVerified()) { notify(user); } }); }
GOOD
function notifyVerifiedUsers(users) { users.filter(isUserVerified).forEach(notify); } function isUserVerified(user) { const userRecord = database.lookup(user); return userRecord.isVerified(); }
Object.assign을 사용해서 기본 개체를 세팅하세요.
BAD
const shapeConfig = { type: "circle", width: 150, height: null }; function createShape(config) { config.type = config.type || "circle"; config.width = config.width || 300; config.height = config.height || 300; } createShape(shapeConfig);
GOOD
const shapeConfig = { type: "circle", width: 150 // height를 제외시켜둔 상태 }; function createShape(config) { config = Object.assign( { type: "circle", width: 300, height: 300 }, config ); ... } createShape(shapeConfig);
플래그는 함수가해야하는 것보다 더 많은 일을하고 있음을 알려주기 때문에 매개 변수로 사용하지 마십시오.
BAD
function createFile(name, isPublic) { if (isPublic) { fs.create(`./public/${name}`); } else { fs.create(name); } }
GOOD
function createFile(name) { fs.create(name); } function createPublicFile(name) { createFile(`./public/${name}`); }
기존 개체를 확장해야하는 경우 네이티브 개체의 프로토 타입 체인에 함수를 만드는 대신 ES 클래스 및 상속을 사용하십시오.
BAD
Array.prototype.myFunction = function myFunction() { // 실행 };
GOOD
class SuperArray extends Array { myFunc() { // 실행 } }
4. 조건문
부정 조건문을 피하세요.
BAD
function isPostNotPublished(post) { // 실행 } if (!isPostNotPublished(post)) { // 실행 }
GOOD
function isPostPublished(user) { // 실행 } if (isPostPublished(user)) { // 실행 }
단축 속성을 사용하세요.
BAD
if (isValid === true) { // 실행 } if (isValid === false) { // 실행 }
GOOD
if (isValid) { // 실행 } if (!isValid) { // 실행 }
조건문을 피하고 다형성과 상속을 사용하세요.
BAD
class Dog { // ... getBreed() { switch (this.type) { case "GermanShepherd": return this.getStandardSize("GermanShepherd"); case "JackRussellTerrier": return this.getStandardSize("JackRussellTerrier"); case "ShibaInu": return this.getStandardSize("ShibaInu"); } } }
GOOD
class Dog { // ... } class GermanShepherd extends Dog { // ... getStandardSize() { return this.standardSize; } } class JackRussellTerrier extends Dog { // ... getSize() { return this.standardSize; } } class ShibaInu extends Dog { // ... getSize() { return this.standardSize; } }
5. ES 클래스 사용
이제는 조금 더 클래스 사용을 선호해야할 필요가 있습니다.
BAD
const Product = function(name) { if (!(this instanceof Product)) { throw new Error("Instantiate Product with `new` keyword"); } this.name = name; }; Product.prototype.getSize = function getSize() { /**/ }; const Tshirt = function(name, color) { if (!(this instanceof Tshirt)) { throw new Error("Instantiate Tshirt with `new` keyword"); } Product.call(this, name); this.color = color; }; Tshirt.prototype = Object.create(Product.prototype); Tshirt.prototype.constructor = Tshirt; Tshirt.prototype.printColor = function printColor() { /**/ };
GOOD
class Product { constructor(name) { this.name = name; } getDiscount() { /* ... */ } } class Tshirt extends Product { constructor(name, color) { super(name); this.color = color; } getSize() { /* ... */ } }
메소드 체이닝을 사용하세요.
코드가 덜 장황 해집니다. 클래스에서 모든 함수의 끝에 이것을 반환하고 추가 클래스 메서드를 연결할 수 있습니다.
BAD
class Product { constructor(name) { this.name = name; } setPrice(price) { this.price = price; } setUnits(units) { this.units = units; } save() { console.log(this.name, this.price, this.units); } } const product = new Product("Bag"); product.setPrice(23.99); product.setUnits(12); product.save();
GOOD
class Product { constructor(name) { this.name = name; } setName(name) { this.name = name; // 체이닝을 위해서 리턴 return this; } setPrice(price) { this.price = price; // 체이닝을 위해서 리턴 return this; } save() { console.log(this.name, this.price, this.units); // 체이닝을 위해서 리턴 return this; } } const product = new Product("T-Shirt") .setName("Jeans") .setAge(31.99) .save();
6. Eval 사용 금지
Eval 함수를 사용하면 JavaScript 컴파일러에 문자열을 전달하고 JavaScript로 실행할 수 있습니다..
eval("alert('Hi');");
Eval 기능은 안전하지 않고 악의적인 프로그래머가 악용할 수있는 잠재적인 위협 벡터를 열어주므로 피해야합니다.
7. JS Lint를 사용하세요.
JSLint는 JavaScript 코드의 일반적인 문제를 식별하는 데 도움이되는 훌륭한 도구입니다.
예를 들어 Visual Studio Code에는 컴파일 타임 (또는 수동)에서 오류를 확인할 수있는 JSLint용 추가 기능이 있습니다.
이렇게하면 코드가 더 깔끔해지며 성가신 버그가 프로덕션에 표시되는 것을 방지하는 데 도움이됩니다.
8. 일반화를 피하세요.
일반적으로 반복하지 않도록 자기 자신이 최선을 다해야 합니다.
중복 코드를 최소화하고, 함수 및 데드 코드와 같은 나쁜 코드를 작성하지 않기 위해 꼼꼼하게 노력해야 할 것입니다.
주석처리하지말고 데드코드 같은경우 삭제를 해버리세요.
감사합니다.
출처 : javascript.plainenglish.io/javascript-clean-code-best-practices-461c24c53cae
'Javascript' 카테고리의 다른 글
127가지 Javascript 유용한 스니펫 (1) (0) 2021.09.12 closest() 실용적으로 사용하기 (0) 2021.06.29 <script async> / <script defer> 언제 사용하면 좋을까? (0) 2021.03.02 Async/Await를 try/catch 없이 사용하기 (0) 2021.03.01 [JS] 자바스크립트 좋은 습관 (object, function, array) (0) 2021.02.07