자바스크립트에서의 this 는 현재 실행 중인 코드에서 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수입니다. 단 this가 가리키는 값, 즉 this 의 바인딩은 함수 호출 방식에 의해 동적으로 결정 됩니다.
※ 핵심 : this 는 함수 호출 방식에 의해 동적으로 결정된다.
1) 첫번째, 일반 함수로 호출된 경우 this는 전역 객체입니다. 그리고 이 this는 브라우저에서 window 객체가 됩니다. (Node.js 에서는 global)
2) 두번째, 메소드로 호출되었다면 this는 해당 메서드가 속한 객체를 가리킵니다
3) 세번째, 함수가 호출될 때 apply, call 또는 bind가 사용되었다면 첫번째 인자로 전달하는 값에 this 를 바인딩 합니다.
4) 마지막으로 함수가 호출될 때 생성자 함수 내부에서의 this 는 생성자 함수가 생성할 인스턴스가 바인딩 됩니다.
기본적으로 this 에는 전역 객체(window)가 바인딩 됩니다.
브라우저에서는 window
, Node.js 환경에서는 global
객체를 가리킵니다.
단, strict 모드에선 undefined
function foo() {
console.log(this)
}
foo() /// window
화살표 함수에서의 this 는 일반 함수와 다르게 동작합니다. 우선 화살표 함수에는 this 가 존재하지 않습니다. 그래서 화살표 함수에서 this 를 사용하면, 외부 스코프의 this 를 그대로 사용합니다.
일반 함수의 this 는 함수가 호출될 때 결정되지만, 화살표 함수는 함수가 정의될때 마치 렉시컬 스코프와 같이 정의 된 위치에 따라 외부 스코프의 this 를 캡쳐해서 사용합니다.
선언식 함수 사용
const person = {
name : 'Seo',
sayName : function() {
innerFun = function() {
return `안녕하세요 ${this.name}님`
}
console.log(innerFun()) /// 안녕하세요 ''님
}
}
person.sayName()
innerFun 함수 앞에 마침표(.) 을 붙여서 호출하지도 않았고, bind, call, apply 를 사용하지도 않았다. 일반 함수 호출 되었기 때문에 여기서 this 는
window
가 된다.
화살표 함수 사용
const person = {
name : 'Seo',
sayName : function() {
innerFun =() => {
return `안녕하세요 ${this.name}님` /// 안녕하세요 Seo님
}
console.log(innerFun())
}
}
person.sayName()
여기서도 innerFun 은 일반함수로 호출 되었으나 innerFun 이 화살표 함수로 선언이 되어 있다. 화살표 함수에서의 this 는 자신의 상위 스코프를 따르기 때문에 여기서 this 는 person 객체 안에 선언된 name 이 된다.
메서드로서 호출된 함수 내부에서 this는 해당 메서드가 속한 객체를 가리킵니다.
sayName 앞에 마침표(.) 를 붙여서 호출한 객체인 person 이 this 가 가리키는 객체가 됩니다.
sayName 앞에 person 을 붙여서 호출 했기 때문에 여기서 this 는 person 객체가 되고 this.name 을 호출하였기 때문에 person.name 값인 'Seo' 가 콘솔에 나오게 됩니다.
const person = {
name : 'Seo',
sayName() {
console.log(this.name)
}
}
person.sayName() //// Seo
✨call 메서드
call 을 사용하면, 함수를 실행하고 함수의 첫번째 인자로 전달하는 값에 this 를 바인딩 합니다. 여기서는 getUser.call(person, 1, 2, 3) 으로 호출하였기 때문에 sayName 의 this 는 person 객체를 가리키게 됩니다.
function getUser(a, b, c) {
console.log(this.name)
console.log(this.gender)
console.log(a + b + c)
}
const person = {
name : 'Seo',
gender : 'Female'
}
getUser.call(person, 1, 2, 3)
/// 'Seo'
/// 'Female'
/// 6
✨apply 메서드
apply 와 call 메서드는 호출할 함수에 인수를 전달하는 방식만 다를 뿐 동일하게 동작합니다. apply 메서드는 호출할 함수의 인수를 배열
로 묶어서 전달합니다.
function getUser(a, b, c) {
console.log(this.name)
console.log(this.gender)
console.log(a + b + c)
}
const person = {
name : 'Seo',
gender : 'Female'
}
const numbers = [1, 2, 3]
getUser.apply(person, numbers)
/// 'Seo'
/// 'Female'
/// 6
✨bind 메서드
bind 는 call, apply 와 조금 다르게 함수를 반환한다라는 독특한 특징이 있습니다. bind 메서드를 이용하면 사용한 함수와 똑같이 생긴 함수를 반환하는 것을 알 수 있습니다. 따라서 bind 메서드를 이용하면 함수를 호출 해줘야 합니다.
function getUser(a, b, c) {
console.log(this.name)
console.log(this.gender)
console.log(a + b + c)
}
const person = {
name : 'Seo',
gender : 'Female'
}
console.log(getUser.bind(person, 1, 2, 3))
// f getUser 함수가 그대로 콘솔에 나타난다.
getUser.bind(person, 1, 2, 3)()
// 따라서 bind 메서드를 사용 후에 다시 한번 호출을 해주어야 this 객체 값을 얻을 수 있다.
생성자 함수 new Circle(5) 을 통해 반지름이 5인 객체를 만들었습니다.
console.log(circle1) 을 확인해보면 radius 가 5이고, getDiameter 함수를 가지고 있는 객체입니다.
function Circle(radius) {
this.radius = radius;
this.getDiameter = function() {
return 2 * this.radius;
}
}
const circle1 = new Circle(5)
const circle2 = new Circle(10);
console.log(circle1)
/// Circle {radius : 5, getDiameter : function()}
console.log(circle1.getDiameter()) /// 10
console.log(circle2.getDiameter()) /// 20
this 는 함수 호출 방식에 따라서 동적으로 결정 됩니다.
1) 글로벌 컨텍스트: this는 전역 객체를 참조합니다. 브라우저 환경에서는 window, Node.js 환경에서는 global 을 나타냅니다.
2) 메소드 내부: 객체의 메소드에서 this를 사용할 경우, this는 해당 메소드를 호출한 객체를 참조합니다.
3) 함수: 일반 함수에서 this는 실행 문맥에 따라 다르게 결정됩니다.
4) 생성자 함수: this는 새로운 객체를 참조합니다. new 키워드로 생성자 함수를 호출할 때, this는 새로 생성된 객체를 가리킵니다.