JavaScript - 클린코드 자바스크립트, 변수 다루기

이소라·2023년 2월 1일
0

JavaScript

목록 보기
19/22

변수 다루기

var를 지양하기

  • var로 선언한 변수

    • 함수 스코프를 가짐
    • 중복 선언할 수 있음
  • var를 사용했을 때 문제점

    • 코드를 실행했을 때, 예측하지 못한 값이 나올 수 있음
  • var를 지양하는 방법

    • var 대신 let, const를 사용해서 변수를 선언하기
    • let과 const로 선언한 변수
      • 블록 스코프를 가짐
      • 중복 선언을 할 수 없음
      • TDZ이 있어서 변수에 값을 할당하기 전에 참조할 수 없음
// var의 경우, 중복 선언 가능
var name = '이름1';
var name = '이름1';

// var의 경우, 재할당 가능
name = '이름2';
// let의 경우, 중복 선언 불가능
let name = '이름1';
let name = '이름1'; // Error

// let의 경우, 재할당 가능
name = '이름2';
// const의 경우, 중복 선언 불가능
const name = '이름1';
const name = '이름1'; // Error

// const의 경우, 재할당 불가능
name = '이름2'; // Error


전역 공간 사용 최소화하기

  • 전역 공간 (최상위 공간)

    • 브라우저 환경 : window
    • NodeJS 환경 : global
  • 전역 공간 사용시 문제점

    • 전역 공간은 런타임 환경에서 스코프가 분리되어 있지 않아서, 어디서나 접근이 가능함
    • 한 파일 내에서 선언한 변수는 다른 파일에서 변경 가능함
    • 전역 공간(window)의 Web API를 수정 가능함 (JavaScript 환경에서는 에러를 발생하지 않음)
  • 전역 공간 사용을 최소화하는 방법

    1. 전역 변수를 만들지 않기
    2. 지역 변수만 만들기
    3. window, global을 조작하지 않기
    4. const, let을 사용하기
    5. IIEE, Module, Closure를 사용하여 스코프를 나누기
// 전역 공간은 어디서나 접근, 변경 가능함
// foo.js
var num = 1;

// bar.js
var num = 2;

// foo => bar => devTool
console.log(num); // 2
console.log(window.num); // 2
// 전역 공간의 Web API를 JavaScript로 수정할 수 있음
// foo.js
var setTimeout = 'setTimeout'

// bar.js
setTimeout(() => {
  // setTimeout API가 실행되지 않음
  console.log('setTimeout'); 
}, 1000);

임시 변수 제거하기

  • 임시 변수

    • 스코프 안에서 전역 변수처럼 사용되는 변수
  • 임시 변수의 문제점

    1. 명령형으로 가득한 코드 로직이 나옴
      • 임시변수를 조작하기 위해 명령형으로 코드를 작성함
    2. 디버깅하기 어려움
      • 임시 변수가 어디서 어떻게 잘못되었는지 알기 어려움
    3. 추가적인 코드를 작성하고 싶은 유혹에 빠지기 쉬움
  • 임시 변수를 제거하는 방법

    1. 함수 나누기
    2. 값을 바로 반환하기
    3. 고차 함수(map, filter, reduce)를 사용하기
    4. 선언형 코드로 바꾸기
// Bad
// 임시 변수 result를 조작할 수 있음
function getElements() {
  const result = {};
  
  result.title = document.querySelector('.title');
  result.text = document.querySelector('.text');
  result.value = document.querySelector('.value');
  
  return result;
}


// Good
// 조작할 수 없게 값을 바로 반환함
function getElements() {
  return {
    title: document.querySelector('.title'),
    text: document.querySelector('.text'),
    value: document.querySelector('.value')
  };
}
// Bad
// let으로 선언한 변수는 조작할 가능성이 있음
function getDateTime(targetDate) {
  let month = targetDate.getMonth();
  let day = targetDate.getDate();
  let hour = targetDate.Hour();
  
  month = month >= 10 ? month : '0' + month;
  day = day >= 10 ? day : '0' + day;
  hour = hour >= 10 ? hour : '0' + hour;
  
  return {
    month, day, hour
  }
}


// Good
// const로 변수들을 선언함
// 조작할 수 없게 값을 바로 반환함
function getDateTime(targetDate) {
  const month = targetDate.getMonth();
  const day = targetDate.getDate();
  const hour = targetDate.Hour();
  
  return {
    month: month >= 10 ? month : '0' + month,
    day: day >= 10 ? day : '0' + day,
    hour: hour >= 10 ? hour : '0' + hour
  }
}
  • 추가적인 스펙이나 날짜에 대한 요구사항이 생겼을 경우, 함수 수정 방법
    • 기존 함수를 재활용해서 요구사항을 반영한 새로운 함수를 만듬
    • 함수를 재활용하기 위해, 함수가 한 역할을 하도록 작성함
// 월, 일, 시간 뒤에 단위를 붙이는 요구사항의 경우
function getDateTimeWithUnit() {
  const currentDateTime = getDateTime(new Date());
  
  return {
    month: currentDateTime.month + '달',
    day: currentDateTime.day + '일',
    hour: currentDateTime.hour + '시',
  }
}

호이스팅 주의하기

  • 호이스팅

    • 런타임시 선언이 최상으로 끌어올려짐
  • 호이스팅의 문제점

    • 코드 작성시 예측하지 못한 실행 결과가 나올 수 있음
  • 호이스팅 주의 방법

    1. var 대신 let, const를 사용하기
    2. 함수 선언문 대신 함수 표현식을 사용하기
// 변수 호이스팅
var global = 0;

function outer() {
  // var로 선언된 global 변수는 최상단으로 끌어올려짐
  // 이 시점에서 global 변수는 선언만 된 상태임
  console.log(outer); // undefined
  var global = 5;
  
  function inner() {
    var global = 10;
    
    console.log(global); // 10
  }
  
  inner();
  
  global = 1;
  
  console.log(global); // 1
}

outer();
// 함수 호이스팅
console.log(sum()); // 10

function sum() {
  return 1 + 2;
}

function sum() {
  return 1 + 2 + 3;
}

function sum() {
  return 1 + 2 + 3 + 4;
}

참고

0개의 댓글