JAVASCRIPT
this 바인딩
객체지향 프로그래밍 언어들은 this라는 키워드를 사용한다. 이 때 this는 해당 코드를 실행하는 클래스의 인스턴스를 나타낸다. JavaScript에도 this라는 키워드가 있는데 JS에서 사용되는 this 는 기존 객체지향 프로그래밍 언어에서의 this와는 다른점이 있기 때문에 객체지향 프로그래밍 언어에 익숙한 사람들은 이해하지 못하는 경우가 있다.
function foo() {
const a = 10
console.log(this.a)
}
foo() // ???
JS를 처음 접할 때 해당 코드에서 출력값은 10일 것이라 기대한다. 하지만 실제로는 10이라는 값이 출력되지는 않는다. JS에서 this가 참조하는 것은 함수가 호출되는 방식에 따라 결정되는데 이것을 this binding이라고 한다.
.
🔎 기본 바인딩 (Default Binding)
어떤 this 바인딩 규칙도 적용되지 않았을 때 적용되는 기본 규칙으로 이 때 this 는 전역 객체에 바인딩된다. (웹일 경우 window, Node.js일 경우 global)
function foo() {
const a = 10
console.log(this.a)
}
foo() // undefined
/*=====================*/
window.a = 10;
function foo() {
console.log(this.a)
}
foo() // 10
위와 같이 window 전역객체에 a라는 프로퍼티가 없을 경우 undefined, 있을 경우는 해당 값이 출력된다. 하지만 엄격모드에서는 기본 바인딩 대상에서 전역객체는 제외되는데 전역객체를 참조해야할 경우 this에는 undefined가 바인딩 된다.
'use strict'
window.a = 20
function foo() {
console.log(this.a)
}
foo() // TypeError: Cannot read property 'a' of undefined
.
🔎 암시적 바인딩 (Implicit Binding)
암시적 바인딩이란, 함수가 객체의 매서드로서 호출되는 상황에서 this가 바인딩 되는 것을 말한다. 이 때 this는 해당 함수를 호출한 객체, 즉 콘텍스트 객체에 바인딩된다.
const foo = {
a: 20,
bar: function () {
console.log(this.a)
}
}
foo.bar() // 20
setTimeout(foo.bar, 1) // ??
암시적 바인딩을 사용할 때 발생할 수 있는 문제는 위와 같은 상황에서 함수를 매개변수(콜백)로 넘겨서 실행할 경우이다. 위 코드에서 setTimeout() 의 결과는 undefined가 나온다. 이유는 setTimeout 함수 안에 전달한 콜백은 bar라는 함수의 레퍼런스일 뿐, foo이 콘텍스트를 가지고 있지 않기 때문이다. 이런 상황을 암시적 바인딩이 소실되었다고 하고 기본 바인딩이 적용되어 전역 객체에 바인딩 된다.
.
🔎 명시적 바인딩 (Explicit Binding)
JS의 모든 함수는 call(), apply(), bind()라는 prototype 메서드를 가지고 있다. 이 3가지 메서드 중 하나를 호출함으로써 this 바인딩을 코드에서 명시하는 것을 명시적 바인딩이라 한다. 이 때 this는 명시한 객체에 바인딩된다.
const foo = {
a: 20
}
function bar() {
console.log(this.a)
}
bar.call(foo) // 20
bar.apply(foo) // 20
const bound = bar.bind(foo)
bound() // 20
.
🔎 new 바인딩 (new Binding)
JS의 new 키워드는 함수를 호출할 때 앞에 new 키워드를 사용하는 것으로 객체를 초기화할 때 사용되는데, 이 때 사용되는 함수를 생성자 함수라고 한다. 생성자 함수에서는 this를 해당 생성자를 이용해 생성할 객체에 대한 참조로 사용한다.
function Foo() {
this.a = 20
}
const foo = new Foo()
console.log(foo.a) // 20
.
🔎 화살표 함수 (Arrow Function)
ES6에 추가된 화살표 함수는 this를 바인딩할 때 앞서 설명한 규칙들이 적용되지 않고 어휘적 스코프(Lexical scope)가 적용된다. 즉, 화살표 함수를 정의하는 시점의 컨텍스트 객체가 this에 바인딩된다.
const foo = {
a: 20,
bar: function () {
setTimeout(() => {
console.log(this.a)
}, 1)
}
}
foo.bar() // 20
.
참조
https://seungtaek-overflow.tistory.com/21