[TIL] 01_ JS | 스코프(scope) & 클로저(closure)

MJ Kim·2021년 8월 2일
3

TIL

목록 보기
1/12

Programmers FE 데브코스 _1일차
스코프는 사실 블록 레벨 스코프를 코딩을 하며 많이 겪어봤언터라 대략 이해는 하고있었다. 하지만.. 클로저... 클로저! 이번 기회에 공부해 보자!


1. 스코프(Scope)

1-1. 스코프(Scope)란?🔍

모든 변수는 스코프(Scope)를 가지며, 변수의 선언 위치에 따라 스코프를 가지게 된다.
스코프(Scope, 유효범위)는 변수가 어느 범위까지 참조되는 지를 뜻한다.

1-2. ES6전 var의 스코프

var x = 'Global';  // <----- 전역변수 (Global variable)

function foo() {
 var y = 'Local';  // <----- 지역변수 (Local variable)
 console.log(x, y);
}

foo(); // Global Local
console.log(x, y); // ReferenceError: y is not defined

위 처럼 함수 내에 선언된 지역 변수선언된 함수 내의 scope를 가지게 되어 외부에서는 참조 할 수 없다.


대부분의 프로그래밍 언어는 (함수, if 문, for 문, while 문, try/catch 문 등) 블록 레벨 스코프(Block-level scope)를 따르지만, 자바스크립트의 var로 선언된 변수는 함수 레벨 스코프(Function-level scope)만을 따랐다.😢
  • for, if, while문 등 해당 블록 내부에서 선언한 변수를 해당 블록 외부에서 참조할 수 있었음. (복잡성 증가)
  • 변수 호이스팅 발생 (변수를 선언하기 이전에 참조)

1-3. ES6이후 let, const의 스코프

var x = 0;
{
  var x = 1;
  console.log(x); // 1
}
console.log(x);   // 1


let y = 0;
{
  let y = 1;
  console.log(y); // 1
}
console.log(y);   // 0


const z = 0;
{
 const z = 1; 
 console.log(z); // 1
}
console.log(z); // 0

ES6는 블록 레벨 스코프를 따르는 변수를 선언하기 위해 let, const 키워드를 제공하게 되었다.😎

  • let : 재할당이 필요한 경우에 사용 (사용 시 변수 스코프는 최대한 좁게 만들기)
  • const: 변경이 발생하지 않는 (재할당이 필요 없는 상수) 원시 값과 객체 선언시 사용

참고

https://poiemaweb.com/es6-block-scope
https://poiemaweb.com/js-scope



2. 클로저(Closure)

2-1. 클로저(Closure)란?🔍

함수가 선언된 환경의 스코프를 기억하여, 함수가 스코프 밖에서 실행될 때에도 기억한 스코프에 접근할 수 있게 만드는 문법이다.
내부함수는 외부함수의 지역변수에 접근 할 수 있는데, 외부함수의 실행이 끝난 후 외부함수가 소멸된 이후에도 내부함수가 외부함수의 변수에 접근 할 수 있다.
이러한 메커니즘을 클로저라고 한다.

function printName(name) {
  const intro = "My name is";
  
  return function() {
    console.log(intro + name);
  };
}

const min = printName("Min");
const bin = printName("Bin");
  
min();  // ----> intro에 접근가능
bin();  // ----> intro에 접근가능

2-2. 클로저(Closure)를 이용한 은닉화

function Counter() {
  // 카운트를 유지하기 위한 자유 변수
  let privateCounter = 0;

  // 클로저
  this.increase = function() {
    return privateCounter++;
  };

  // 클로저
  this.decrease = function() {
    return privateCounter--;
  };
  
  // 클로저
  this.value = function() {
    return privateCounter;
  };
}

const counter = new Counter();

console.log(counter.value()); // 0
counter.increase(); 
counter.increase(); 
counter.decrease(); 
console.log(counter.value()); // 1

생성자 함수 Counter 내부에서 선언된 변수 counter는 생성자 함수 Counter 외부에서 접근할 수 없다. 그러나 생성자 함수 Counter가 생성한 인스턴스의 메소드인 increase, decrease는 클로저이기 때문에 Counter의 변수 counter에 접근할 수 있다. 이러한 클로저의 특징을 사용해 내부변수와 함수를 숨길 수 있다.



2-3. 클로저(Closure) 은닉화 참고

클래스 컴포넌트를 작성하지 않아도 state와 같은 특징들을 사용할 수 있는 Hooks 기능
https://ko.reactjs.org/docs/hooks-effect.html

참고

https://poiemaweb.com/es6-block-scope
https://poiemaweb.com/js-closure
https://velog.io/@proshy/JS%ED%81%B4%EB%A1%9C%EC%A0%B8closure%EC%99%80-%ED%81%B4%EB%A1%9C%EC%A0%B8%EC%9D%98-%EC%82%AC%EC%9A%A9-%EC%98%88%EC%A0%9C
https://opentutorials.org/course/743/6544

profile
기초가 튼튼한 개발자로 성장하기 💻 🤞

0개의 댓글