Named function, arrow function this 바인딩
function regular() {
console.log('This is a regular function.');
}
regular();
const arrow = () => {
console.log('This is an arrow function.');
}
arrow()
- 위와 같이 JavaScript 에는 일반 함수와 화살표 함수가 존재하며 둘은 사실 약간의 차이가 존재합니다.
- 이는 아래와 같습니다.
function greet() {
console.log('greet():', this);
console.log();
}
greet();
- 위는
named function
이라고 부르며 일반적이고 정통적인 형태를 가진 함수입니다.
named function
은 위처럼 독립적인 함수 형태로 호출이 된다면 this
값은 global object
값을 가집니다.
- 여기서 독립적인 함수 형태란 메소드 형태가 아닌 함수 원형으로 호출되는 방식을 말하며
greeet()
과 같은 호출 방식을 말합니다. 이 경우, this
값은 global object
를 가집니다.
- 반대로 메소드란 객체에 달려있는 함수로서
person.greet()
와 같은 객체의 메소드를 호출하는 방식을 말합니다. 이 경우, this
값은 자동으로 해당 객체에 바인딩 됩니다.
const person = {
name: 'John',
greet: function() {
console.log('person.greet():', this.name);
const namedFunction = function() {
console.log('namedFunction():', this.name);
}
namedFunction();
const arrowFunction = () => {
console.log('arrowFunction():', this.name);
}
arrowFunction();
}
}
person.greet();
person.greet(): John
namedFunction(): undefined
arrowFunction(): John
- 위의 코드에는
person
객체가 있으며 해당 객체는 greet()
메소드를 가지고 있습니다.
- 해당 메소는 처음에 바로
this.name
값을 출력합니다.
- 이때 해당 함수는
person.greet()
를 통해 호출되므로 메소드 형식으로 호출되었습니다. 따라서 첫번째 this
값은 person
객체에 자동으로 바인딩 되므로 John
을 출력합니다.
- 이어서
namedFunction()
함수를 호출합니다.
- 해당 함수는
standalone
함수로 독립적으로 호출된 함수입니다. 따라서 this
값은 전역 객체를 가리키지만 전역 객체는 name
속성을 가지고 있지 않으므로 undefined
값을 출력합니다.
- 마지막으로
arrowFunction()
함수를 호출합니다.
- 해당 함수는 화살표 함수이며 화살표 함수는
this
값을 가지고 있지 않습니다. 하지만 가장 가까운 상위 객체의 this
값을 상속받으므로 이 경우 person
객체가 되며 John
을 출력할 수 있습니다.
function strictModeGreet() {
'use strict';
console.log('strictModeGreet():', this);
console.log();
}
strictModeGreet();
- 지금까지
non-strict mode
인 경우에 대해 알아보았고 위 경우는 strict mode
를 사용했을 때 입니다.
strict mode
에서 함수를 호출한다면 this
값은 전역 객체가 아닌 undefined
를 가리킵니다.
- 따라서 함수의 타입과 호출 방식, 그리고
strict mode
의 여부에 따라 this
값이 달라짐을 확인할 수 있습니다. 이를 정리하자면 아래와 같습니다.
Named functions
Non-Strict Mode
named function
이 독립적으로 호출되면(i.e., 메소드 형식으로 호출되지 않으면), 함수 내부의 this
값은 global object
값을 가리킵니다(브라우저의 경우 windonw 객체). 또는 JavaScript 환경에 따라서 undefined
.
named function
이 메소드 형태로 호출되면(i.e., object.method()), 함수 내부의 this
값은 해당 객체에 자동으로 바인딩 됩니다. this
값은 함수 호출의 맥락에 따라 런타임에 동적으로 결정됩니다.
Strict Mode
strict mode
에서 named function
이 독립적으로 호출되면, 함수 내부의 this
값은 undefined
값을 가집니다.
- 이는
this
값의 디폴트 바인딩이 global object
를 가리키는걸 예방해 줍니다.
Arrow functions
Non-Strict Mode and Strict Mode
arrow function
은 자신의 this
값을 가지지 않습니다. 대신에 가장 가까운 상위 렉시컬 범위에서 이 값을 상속받습니다. 이를 lexical scoping
이라고 부릅니다.
- 함수 내부의
this
값은 화살표 함수가 어떻게 호출되는지 또는 어디에서 호출되는지에 따라 변경되지에 영향을 받지 않습니다.
github