IT를 공부하자

자바스크립트 기본 개념 정리 #2 본문

자바스크립트

자바스크립트 기본 개념 정리 #2

낭만공돌이 2023. 1. 19. 07:25
반응형

클로저

클로저는 함수와 그 함수가 선언된 렉시컬 환경과의 조합이다.

뭔 소리인지...

 

실행컨텍스트

실행할 코드에 제공할 환경 정보들을 모아놓은 객체. 이를 콜 스택에 저장해서 처리.

 

아래 예는 코어 자바스크립트 책에서 발췌하였음.

실행 컨텍스트와 콜스택 예제 코드
실행 컨텍스트의 콜스택 처리 과정
활성화된 실행 컨텍스트의 수집 정보

렉시컬 스코프 정의

자바스크립트 엔진은 함수를 어디서 호출했는지가 아니라 함수를 어디에 정의했는지에 따라 상위 스코프를 결정한다. 이를 렉시컬 스코프(정적 스코프)라 한다.

자유변수(free variable)

매개변수나 지역변수로 선언되지 않은 다른 변수

 

또 다른 책에서는 이렇게 클로저를 정의한다.

자유 변수를 포함하는 함수를 클로저라 부른다.

 

점점더...

 

구글검색으로 좀 더 자세하게 설명하는 블로그에서 아래와 같은 설명을 찾아 보았다. 뭔가 더 정리가 되는 느낌이다.

위 정의에서 말하는 “함수”란 반환된 내부함수를 의미하고 “그 함수가 선언될 때의 렉시컬 환경(Lexical environment)”란 내부 함수가 선언됐을 때의 스코프를 의미한다. 즉, 클로저는 반환된 내부함수가 자신이 선언됐을 때의 환경(Lexical environment)인 스코프를 기억하여 자신이 선언됐을 때의 환경(스코프) 밖에서 호출되어도 그 환경(스코프)에 접근할 수 있는 함수를 말한다. 이를 조금 더 간단히 말하면 클로저는 자신이 생성될 때의 환경(Lexical environment)을 기억하는 함수다라고 말할 수 있겠다.

출처 : https://poiemaweb.com/js-closure

 

그래서 어디에 쓰는데?

전역변수의 사용을 억제하고 상태값을 유지하는데 사용한다고 한다. 자세한 예제와 설명이 위 사이트에 나와 있으니 추가 정리는 하지 않고 링크로 대체한다. 즉 상태값 유지를 위해 즉시 실행 함수 안에 설정한 변수 값을 기억하기 위해 함수를 반환하도록 하여 클로저를 생성한다. 이 클로저를 통해 한번 호출되고 없어져 버린 즉시 실행함수의 변수를 사용할 수 있다. 즉시 실행함수는 한번만 실행되기에 이 함수에서 정의된 지역 변수는 다시 초기화되는 일이 없기 때문에 아주 유용하다.

 

this

자바스크립트의 this라는 특별한 키워드를 사용할 수 있는데 읽기 전용 값이고 함수를 호출한 방법에 의해 값이 달라짐

 

일반함수에서는 전역 객체를 가르킴

function func() {
  console.log(this===window); //true
}
func();

생성자 함수는 호출하여 생성된 객체를 가르킴

function Vehicle(type) {
  this.type = type;
}
const car = new Vehicle('Car');

객체의 함수인 메서드를 호출하면 메서드를 소유하고 있는 객체를 가르킴

const obj = {
  lang: 'javascript',
  greeting() {
    console.log(this);  // obj 객체로 바인딩 됨.
    return `hello ${this.lang}`;
  }
}

console.log(obj.greeting()); // 'hello javascript'

const greeting = obj.greeting;
console.log(greeting()); // 'hello undefined'

단, 메서드를 어떻게 호출했는지에 따라 this 바인딩이 달라진다.

 

call(), apply(), bind()

함수 내장 메서드로 함수 호출 방법에 상관없이 this를 특정한 객체로 바인딩할 수 있다. 이를 명시적 바인딩이라고 한다.

 

call()과 apply()는 어떤 함수를 다른 객체의 메서드처럼 호출할 수 있게 한다. 첫 번째 인자는 this로 바인딩할 객체를 받는다. 그 이후 인자는 함수의 인자로 사용된다. apply()는 call()과 동일한 동작을 하나 2번째 인자를 배열로 받는다.

const obj = { name: 'javascript' };

function greeting() {
  return `hello ${this.name}`;
}

console.log(greeting.call(obj)); // 'hello javascript'



const obj = { name: 'Lee' };

function getUserInfo(age, country) {
  return `name: ${this.name}, age: ${age}, country: ${country}`;
}

console.log(getUserInfo.call(obj, 20, 'Korea'));  // 'name: Lee, age: 20, country: Korea'

bind() 메서드는 call(), apply()와 다르게 this 바인딩을 영구적으로 변경한다. bind() 메서드는 함수가 어디에서 호출되는지에 상관없이 this값을 고정하고 싶을 때 사용한다. bind()를 사용하면 새로운 함수를 반환한다.

const obj1 = { name: 'Lee' };
const obj2 = { name: 'Han' };

function getUserInfo(age, country) {
  return `name: ${this.name}, age: ${age}, country: ${country}`;
}

count bound = getUserInfo.bind(obj1);

console.log(bound(20, 'Korea')); // 'name: Lee, age: 20, country: Korea'
console.log(bound.apply(obj2, [20, 'Korea'])); // 'name: Lee, age: 20, country: Korea' 변경이 안됨

화살표 함수의 this

화살표 함수의 this는 화살표 함수를 둘러싸고 있는 렉시컬 스코프에서 this의 값을 받아 사용한다.

const obj = {
  name: 'javascript',
  greeting() {
    setTimeout(()=> {
      console.log(this.name);
    }, 1000);
  }
}

 

'자바스크립트' 카테고리의 다른 글

자바스크립트 기본 개념 정리 #1  (0) 2023.01.16
Comments