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