자바스크립트 클린코드에 대한 관점들이 많이 있습니다.
다른사람들을 위한 코드를 작성하는 것이 좋고, 또 그 자체로도 본인에게도 매우 도움이 되기 때문에 어떻게 보면, 클린코드는 좋은 개발자의 덕목에 필수불가결하다고 할 수 있습니다.
여전히 어지럽고 난해한 코드를 작성하는 법, 아무도 알아보지 못하게 코드를 작성하는 법에 대한 책들이 있긴 하지만, 저는 그런 관점에 대해서는 자기 자신이 자신이 없기 때문이라는 생각만 듭니다.
이 글에서는 자바스크립트 관점에서만 다룹니다.
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 |
댓글