HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
👻
개발 기록
/
📑
강의 정리
/
📑
클린코드 자바스크립트
📑

클린코드 자바스크립트

Created
Mar 19, 2022 01:54 PM
Type
클린코드 JS
Mento
Poco jang
Created By
  • node.js는 크롬 v8 JS 엔진으로 빌드된 JS 런타임이다.
 

변수 다루기

  • var를 지양하자.
    • var는 재할당, 재선언 그리고 선언 전 호출시 단순히 undefined만 나오기 때문에 위험함.
    • var는 block scope가 아닌 function scope이기 때문에 if 문에서 재할당을 했을 때 전역 변수에도 영향을 줌. block scope는 사람이 생각하듯이 코딩을 하기 때문에 더욱 안전하게 코드를 작성할 수 있음.
var global = '전역' if(global === '전역') { var global = '지역' console.log(global) //지역 } console.log(global) //지역
let global = '전역' if(global === '전역') { let global = '지역' console.log(global) //지역 } console.log(global) //전역
  • const는 재할당만 금지이고 push등 객체, 배열 조작엔 이상이 없음.
  • 전역은 최상위 공간이란 뜻이고 최상위에는 브라우저(window)와 node JS(global) 환경이 있음.
    • 전역 공간에 접근하면 안되는 이유.
      • 어디서나 접근할 수 있기 때문에.
      • 파일을 나눠도 scope에 따라 코드르 공유하기 때문에 index.js에서 선언한 변수를 index2.js에서 호출할 수 있는 문제가 발생. 즉, 스코프 분리가 안됨.
      • setTimeout 등 api를 변수명으로 사용하여도 코드 상으로 에러가 나지않지만 런타임에서 에러가 남.
      • 따라서 지역 변수를 사용하고 window, global을 직접 조작하지 말자.
      • IIFE, Module, closure, 스코프 나누기가 대안이 될 수 있음.
  • 임시 변수 제거하기
    • 임시 변수는 함수의 맥락을 예측하기 어렵고 명령형 코드로 가득해진다. 이에 따라 추가적인 코드를 작성하게 하여 하나의 역할 규칙을 깨기 쉽게 만든다.
    • 해결책은 바로 반환, 함수 나누기, 고차함수(map, filter, reduce) 사용, 선언형 코드 사용.
  • 호이스팅 주의하기
    • 호이스팅은 런타임에 선언과 할당이 분리되어 선언을 최상단으로 끌어올려주는 것을 말함. 런타임에 분리가 되기 때문에 undefined가 호출되는 이유를 빠르게 파악하기 어려움.
    • 또한 함수는 호이스팅 되기 때문에 혼란해짐.
    • 함수 표현식으로 익명 함수를 만들어 변수에 할당하면 위와 같은 문제를 해결할 수 있음.
    • const sum = fuction() { return 1 + 2; }
 

타입 다루기

  • 타입 검사
    • typeof가 만능은 아님.
    • JS에는 원시 타입과 참조 타입이 있음. 이때 참조 타입은 변하기 때문에 typeof로 타입을 알아내기 어려움.
    • 특히 null의 타입을 검사하면 object로 나옴. JS 오류이고 고칠 수 없다고 인정을 함.
    • JS는 동적 언어이기 때문에 타입까지 동적일 수 있기 떄문에 타입 검사가 어렵고 잘 찾아봐야 함.
    • instanceof로도 타입을 검사할 수 있음. 객체 확인이 용이함. 하지만 최상위 object 타입은 검사할 수 없음.
    • 이에 대한 대안으로 Object.prototype.toString.call()로 판별할 수 있음.
    • function Car(make, model, year) { this.make = make; this.model = model; this.year = year; } const auto = new Car('Honda', 'Accord', 1998); console.log(auto instanceof Car); // true console.log(auto instanceof Object); // true Object.prototype.toString.call(auto) // [object Object] const arr = [] const func = fuction() {} const date = new Date() Object.prototype.toString.call(func) // [object Function]
  • undefined & null
    • null은 비어있는 값을 명시적으로 지정함. 단 숫자적으로 표현했을 땐 0임.
    • undefined는 아무것도 지정하지 않았을 때의 기본 값. 예를 들어 변수만 선언하고 값을 할당하지 않은 상태에 undefined임. 참고로 undefined는 NaN임.
    • 이 둘은 헷갈리기 때문에 스스로의 컨벤션을 만드는 것이 좋음.
  • eqeq 줄이기
    • 동등 연산자(==)를 말함.
    • 이 둘의 차이는 형 변환 유무임. ==는 형변환을 하고 ===는 하지 않음. 이때 ==는 형변환을 해버리기 때문에 신중하게 사용해야 함. 사람이 봤을 땐 느슨한 검사를 하는 것 같지만 실제론 암묵적인 형변환이 일어나는 것임.
    • 대신 Number등 형 변환을 수동으로 해서 비교를 하는 방법을 추천함.
  • 형변환 주의하기
    • parseInt에 두 번째 인자로 10을 지정하는 것이 좋음. 10진수가 기본이 아니기 때문.
    • 암묵적인 변환이 아닌 명시적인 형변환을 해주자.
  • isNaN
    • 2진수와 10진수 사이의 간극이 소수점임.
    • IEEE 754라는 부동소수점으로 해결을 하려 함.
    • isNaN은 숫자가 아니다라는 의미이기 때문에 typeof로 판별을 할 경우 헷갈릴 수 있음.
      • isNaN(123)은 false임. 숫자가 숫자가 아니다 → 숫자다.
      • 따라서 Number.isNaN()으로 검사하는 것을 추천함. 엄격한 검사를 할 수 있음.

경계 다루기

  • min - max
    • 최소값, 최대값이 포함 여부를 결정해야 함(이상-초과, 이하-미만).
    • ex) MIN_NUMBER_LIMIT, MIN_IN_NUMBER
  • begin - end
    • 주로 날짜가 쓰이는 달력 등에 사용되는 표현임.
  • first - last
    • min과 max의 범위 내에 숫자가 모두 존재하는 것이 아닌 일부만 있을 때 고려할 수 있는 변수명임.
  • prefix - suffix
    • prefix는 시아버지의 시 등 접두사를 의미함.
    • suffix는 덮개, 지우개의 개처럼 접미사를 의미함.
    • 코드를 읽는 일관성을 만들 수 있음.
    • 예를 들어 리액트는 use가 붙으면 hook임을 알 수 있음. 이 외에도 jquery의 $나 JS의 #이 있음.
    • 컴포넌트를 만들 때 이를 적용해 볼 수 있음. ex) baseButton, baseTable
    • 네트워크 상태를 접미사로 보여줄 수 있음. ex) STARRED_REQUEST, STARRED_SUCCESS
  • 매개변수의 순서가 경계다
    • 매개변수를 2개가 넘지 않도록 하자.
    • 3개 이상이라면 객체로 받거나 스프레드 연산자를 쓰자.
    • 래핑 함수를 만들자.
    • function someFunc(one, two, three, four) {} function getFunc(one, three) { someFunc(one, undefined, three) // someFunc 매개변수 부분을 객체로 만들면 순서를 지키지 않아도 됨. }
       

      객체 다루기

    • computed property name
      • []를 사용하면 객체의 key값도 변수로 만들 수 있음.
    • lookup table
      • function getUserType(type) { switch (type) { case 'ADMIN' : return '관리자'; case 'INSTRUCTOR' : return '강사'; default: return '해당 없음'; } }
        function getUserType(type) { const USER_TYPE = { ADMIN : '관리자', INSTRUCTOR: '강사' } return USER_TYPE[type] ?? '해당 없음'; // ||는 falsy한 값을 대응하지 못함. }
        function getUserType(type) { return ( { ADMIN : '관리자', INSTRUCTOR: '강사' }[type] ?? '해당 없음' );