스코프와 클로저 (2)

Woogie·2022년 10월 18일
0

PGDC_JavaScript

목록 보기
4/5
post-thumbnail

스코프 (Scope, 유효범위)

스코프란?
ES5까지는 함수 레벨 스코프까지 지원했다.
함수 선언식으로 만들어진 함수 내부 전체에 유효한 식별자가 되어 아래 코드 처럼 에러 없이 콘솔이 찍힌다.

// 함수 레벨 스코프
function foo() {
  if(true) {
    var color = "blue";
  }
  console.log(color); // blue
}

하지만 ES6부터는 블록 레벨의 스코프를 지원한다.
아래 코드처럼 let, const 키워드를 통해 블록 레벨 스코프 사용이 가능하다.

function foo() {
  if(true) {
    let color = "blue";
    console.log(color);	// blue;
  }
  console.log(color); // ReferenceError: color is not defined
}

전역 범위에 변수가 선언된 경우 전역 변수라고 하며 Global Scope라고 한다.
블록 내부에 변수가 선언된 경우 지역 변수라고 하며 Local Scope라고 한다.

const a = 5;	// Global Scope
{
  const b = 3;	// Local Scope
  conosle.log(a,b);
  // 5 3
}
console.log(a,b);
// Error

클로저 (Closure)

클로저란?
함수가 선언된 환경의 스코프를 기억하여 함수가 스코프 밖에서 실행될 때에도 기억한 스코프에 접근할 수 있게 만드는 문법

자바스크립트에선 함수가 실행이 완료되어도 메모리를 바로 해제하지 않는다.
변수가 여전히 다른 함수에서 참조되고 있다면 메모리에 남겨두기 때문에 참조 가능하다.
이러한 성질 때문에 아래와 같은 코드가 실행될 수 있다.

function testFunc() {
  let localVar = 2;
  
  return function() {
    console.log(`localValr = ${lcalVar}`);	// testFunc 지역 변수 참조
  }
}

let returnedFunc = testFunc();
returnedFunc();	// localVar = 2

이런 클로저를 유용하게 사용하는 방법 중 하나는 은닉화이다.
아래의 코드처럼 내부 변수와 함수를 숨길 수 있다.

function Counter() {
  let privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }
  
  return {
    increment: function () {
      changeBy(1);
    },
    decrement: function () {
      changeBy(-1);
    },
    value: function() {
      return privateCounter;
    },
  };
}

const counter = Counter();

console.log(counter.value()); // logs 0
counter.increment();
counter.increment();
console.log(counter.value()); // logs 2
counter.decrement();
console.log(counter.value()); // logs 1

자바와 같은 몇몇 언어들은 메소드를 프라이빗으로 선언할 수 있는 기능이 있다.
하지만 자바스크립트는 태생적으로 이런 방법이 없어서 클로저의 성질을 이용하여 프라이빗 메소드를 흉내내는 것이 가능하다고 한다. 🙄

출처

프로그래머스 데브코스
티스토리
MDN 클로저

profile
FrontEnd Developer

0개의 댓글