모던 자바스크립트 딥다이브, 면접과 함께 공부하기 - 14장 전역 변수의 문제점

지인·2023년 7월 22일
0

DeepDive

목록 보기
11/17
post-thumbnail

💡 아래 내용은 모던 자바스크립트 딥다이브를 공부하며 이해했던 내용을 다루고 있습니다. 혹시 틀렸거나 잘못된 정보가 있다면 알려주세요!

📌 14장 전역 변수의 문제점

14.1 변수의 생명 주기

JS에서 변수의 생명 주기는 변수가 선언되는 순간부터 해당 변수가 가비지 컬렉션에 의해 메모리에서 제거되는 순간까지를 말합니다.

14.1.1 지역 변수의 생명 주기

지역 변수는 함수 내부에서 선언된 변수입니다. 변수 선언, 변수 초기화 및 할당, 변수 사용, 변수 해제의 순서로 생명 주기가 진행됩니다. 각 주기별 자세한 동작은 다음과 같습니다.

  1. 변수 선언: 함수 내에서 var, let, const 키워드를 사용하여 지역 변수를 선언합니다.

  2. 변수 초기화 및 할당: 선언된 지역 변수는 초기화 단계를 거치며, 이 단계에서 var 키워드로 선언된 변수는 undefined로 초기화되고, let과 const 키워드로 선언된 변수는 선언 후 별도로 초기화해야 합니다. 초기화 후에는 해당 변수에 값을 할당할 수 있습니다.

  3. 변수 사용: 함수 내에서 지역 변수는 해당 함수의 실행 컨텍스트가 유지되는 동안에만 접근 및 사용이 가능합니다.

  4. 변수 해제: 함수가 실행을 완료하고 실행 컨텍스트가 사라질 때, 그 함수 내에서 선언된 지역 변수도 함께 해제됩니다. 이는 함수 실행 컨텍스트가 사라지면 그 안에서 선언된 지역 변수에 대한 참조가 사라지므로, 가비지 컬렉터가 해당 메모리를 회수할 수 있게 되기 때문입니다.

따라서 지역 변수는 함수가 호출될 때 생성되고, 함수가 종료될 때 사라지는 생명 주기를 가집니다. 이러한 특성 덕분에 지역 변수는 함수 내에서만 필요한 데이터를 임시로 저장하는 데 매우 유용합니다

지역 변수의 생명 주기는 함수의 생명 주기와 일치한다.

함수 내에서 var 키워드 없이 선언한다는게 어떤건가요?

키워드 없이 변수를 선언하는 것은 코드의 유지 관리와 디버깅을 어렵게 만들 수 있으므로, 일반적으로는 권장되지 않습니다. 항상 적절한 키워드(var, let, const)를 사용하여 변수를 선언하는 것이 좋습니다.

function example() {
  globalVar = "I'm a global variable!";
}
example();
console.log(globalVar);  // "I'm a global variable!"

14.1.2 전역 변수의 생명 주기

전역 변수는 함수 내부에서 선언된 변수입니다. 마찬가지로 변수 선언, 변수 초기화 및 할당, 변수 사용, 변수 해제의 순서로 생명 주기가 진행됩니다. 각 주기별 자세한 동작은 다음과 같습니다.

  1. 변수 선언: 코드의 어느 위치에서든지 전역 변수를 선언할 수 있습니다. 전역 스코프에서 var, let, const 키워드를 사용해 변수를 선언하거나, 함수 내에서 var 키워드 없이 변수를 선언함으로써 전역 변수를 생성할 수 있습니다.

  2. 변수 초기화 및 할당: 선언된 전역 변수는 초기화 단계를 거칩니다. 이때 var 키워드로 선언된 변수는 undefined로 초기화되며, let과 const 키워드로 선언된 변수는 선언 후 별도로 초기화해야 합니다. 초기화 후에는 해당 변수에 값을 할당할 수 있습니다.

  3. 변수 사용: 전역 변수는 코드의 어느 위치에서든지 접근 및 사용이 가능합니다.

  4. 변수 해제: 전역 변수의 생명 주기는 웹 페이지나 Node.js 애플리케이션의 생명 주기와 동일합니다. 즉, 웹 페이지가 닫히거나 Node.js 애플리케이션이 종료될 때 전역 변수도 메모리에서 해제됩니다.

따라서 전역 변수는 웹 페이지나 애플리케이션이 실행되는 동안 계속 메모리에 유지되므로, 메모리 사용에 주의해야 합니다. 또한, 너무 많은 전역 변수를 사용하면 변수 이름이 충돌할 위험이 있으므로 주의해야 합니다.

14.2 전역 변수의 문제점

네임스페이스 오염: 전역 변수는 어디서든 접근이 가능하므로, 변수 이름이 충돌하는 문제가 발생할 수 있습니다. 여러개의 스크립트를 사용하는 경우, 같은 이름의 전역 변수가 존재하면 예상치 못한 동작을 할 수 있습니다.

암묵적 결합: 전역 변수는 애플리케이션 어디에서든 변경할 수 있기 때문에, 이는 모든 코드가 전역 변수를 참조하고 변결할 수 있는 암묵적 결합을 허용하는 것이다.

긴 생명 주기: 전역 변수는 애플리케이션의 생명 주기 동안 메모리에 남아있기 때문에, 불필요하게 메모리를 사용하게 될 수 있습니다.

스코프 체인 상 종점에 존재: 변수를 검색할 때, 전역 변수가 가장 마지막에 검색되기 때문에, 전역 변수의 검색 속도가 가장 느리다.

보안 이슈: 악의적인 스크립트가 전역 변수에 접근하여 변경하는 등의 보안 문제가 있을 수 있습니다.

14.3 전역 변수의 사용을 억제하는 방법

14.3.1 즉시 실행 함수

즉시 실행 함수 내부에 선언된 변수는 전역 스코프에 영향을 주지 않습니다.

(function () {
  var foo = 10;
  // ...
}());

console.log(foo); // error

14.3.2 네임스페이스 객체

가능한 한 적은 수의 전역 변수만 사용하는 패턴입니다. 이 패턴에서는 모든 변수와 함수를 하나의 전역 객체에 넣어서 관리합니다.

var MyApp = {};
MyApp.someVariable = 'Hello';
MyApp.someFunction = function() {
    return MyApp.someVariable;
};

14.3.3 모듈 패턴

모듈 패턴은 특정 코드 조각을 별도의 코드 유닛으로 캡슐화하는 방법입니다. 모듈 패턴의 주요 목적은 private(비공개)와 public(공개) 요소의 분리입니다. JS에서는 접근 제한자를 제공하지는 않는다.

var counterModule = (function () {
  var counter = 0; // private 변수

  var changeBy = function (val) {
    counter += val;
  };

  return {
    increment: function () {
      changeBy(1);
    },

    decrement: function () {
      changeBy(-1);
    },

    value: function () {
      return counter;
    }
  };  
})();

console.log(counterModule.value()); // 출력: 0
counterModule.increment();
counterModule.increment();
console.log(counterModule.value()); // 출력: 2
counterModule.decrement();
console.log(counterModule.value()); // 출력: 1

14.3.4 ES6 모듈

코드를 여러 파일로 분리하여 각 파일이 다른 파일에 정의된 코드를 가져다 사용할 수 있도록 만드는 기능입니다. ES6 모듈 시스템은 모듈 간의 종속성을 명확하게 표현하고, 모듈을 재사용하는데 유용한 메커니즘을 제공합니다. 대부분의 프론트엔드 프로젝트에서는 웹팩(Webpack)과 같은 모듈 번들러를 사용하여 ES6 모듈을 사용하고 관리합니다.

// math.js
export function add(x, y) {
  return x + y;
}
// app.js
import { add } from './math.js';

console.log(add(1, 2));  // 3
profile
안녕하세요

1개의 댓글

comment-user-thumbnail
2023년 7월 22일

이런 유용한 정보를 나눠주셔서 감사합니다.

답글 달기