Skip to main content

[JavaScript] this

· 6 min read

javascript에서는 this의 동작에 대해 이해를 하려면 Execution ContextLexical Environment를 이해해야한다.

Execution Context

  • 자바스크립트 엔진은 실행이 가능한 코드를 만나면 Execution Context를 생성한다.
  • 매번 함수의 호출마다 새로운 Execution Context가 생성된다
  • EC는 Lexical Environment, Variable Environment, ThisBinding에 대한 정보를 가지고 있다.

Lexical Environment Object

  • 자원을 어디에서 찾을 것인가?
  • 해당 Context에서 선언된 변수/함수들의 Reference 값을 저장하는 객체
  • EC 생성 초기 시점에는 Variable Environment와 동일한 값을 가지나, 바인딩된 값들에 따라 변경된다.

Variable Environment Object

  • Lexical Environment에 포함되는 개념
  • 내부에 선언된 변수, 함수 선언, 함수 매개 변수 들을 저장한다.
  • 값이 절대로 변하지 않는다.

ThisBinding

  • ThisBinding은 함수의 호출 시점에 정해지며, this 키워드를 말한다.
  • this는 함수가 현재 어느 EC에서 구동하고 있는 지를 알려준다.
  • ThisBinding이 null, undefined이면 기본으로 global(window)를 대입한다.
  • 단, 'use strict' 모드인 경우에는 null로 대입한다.

자바스크립트에서의 this 예시

this는 함수의 현재 실행 문맥을 말한다. 즉, 함수가 호출된 시점에서 포함된 객체를 찾아서 this에 바인딩한다.

var item = 'global item!';
var obj = {
item: 'item from obj',
mtd: function() {
console.log('this === window : ', this === window);
console.log('this === obj : ', this === obj);
console.log(this.item);
}
}

var mtd = obj.mtd;
mtd();
obj.mtd();
/**
this === window : true
this === obj : false
global item!

this === window : false
this === obj : true
item from obj
**/

함수 실행에서의 this

일반적인 함수 실행에서의 this는 전역 객체이다.

function func() {
console.log('in func, this === window : ', this === window);
console.log('in func, this === undefined : ', this === undefined);
}
func();
console.log('out func, this === window : ', this === window);
/*
in func, this === window : true
in func, this === undefined : false
out func, this === window : true
*/

하지만 strict mode를 선언하는 경우에는 함수 내부에서 this 는 전역 객체가 아니다.

'use strict';
function func() {
console.log('in func, this === window : ', this === window);
console.log('in func, this === undefined : ', this === undefined);
}
func();
console.log('out func, this === window : ', this === window);
/*
in func, this === window : false
in func, this === undefined : true
out func, this === window : true
*/

strict mode 선언을 함수 스코프 내에서만 적용되도록 사용할 수 있다.

function strictFunc() {
'use strict';
console.log('in strictFunc, this === window : ', this === window);
console.log('in strictFunc, this === undefined : ', this === undefined);
}

function func() {
console.log('in func, this === window : ', this === window);
console.log('in func, this === undefined : ', this === undefined);
}

func();
strictFunc();
console.log('out func, this === window : ', this === window);
/*
in func, this === window : true
in func, this === undefined : false
in strictFunc, this === window : false
in strictFunc, this === undefined : true
out func, this === window : true
*/

bind & apply & call

bind, apply, call 메서드는 this에 강제로 해당 메서드를 호출한 함수를 바인딩 시킨다. bind 메서드는 바인딩 후 새로운 함수를 반환하는 반면, apply 메서드는 해당 함수를 호출한다. call 메서드는 apply 메서드와 동일하나 여러 개의 파라미터를 전달받을 수 있다.

bind 메서드 예시

function speakNation() {
console.log(this.nation);
}

var person = {
name: 'Hong Kil Dong',
nation: '한국',
};

var hongSpeakNation = speakNation.bind(person);
hongSpeakNation();

apply 메서드 예시

function speakNation() {
console.log(this.nation);
}

var person = {
name: 'Hong Kil Dong',
nation: '한국',
};

speakNation.apply(person);

ES6 - Arrow Function

Arrow Function을 사용하면 현재 실행 시점의 this를 가르키는 것이 아니라, 상위 스코프의 this를 가르킨다.

const job = {
items: ['teacher', 'baker', 'student'],
find() {
this.items.findIndex(function (item) {
console.log('this === window : ', this === window); // true
});
this.items.findIndex((item) => {
console.log('this === window : ', this === window); // false
});
},
};
job.find();

Reference