뚜벅

모던 자바스크립트 Deep Dive - this 본문

JavaScript

모던 자바스크립트 Deep Dive - this

초코맛젤리 2022. 12. 25. 06:15

자바스크립트 this에 대해 정리합니다.

 

this 정의

- 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수다. 

- this를 통해 자신이 속한 객체 또는 자신이 생성할 인스턴스의 프로퍼티나 메서들를 참조할 수 있다.

this 사용

자바스크립트에서 this 바인딩은 함수 호출 방식에 의해 동적으로 결정된다.

 

- 전역에서 this 

this는 어디서든 참조 가능하다.

그리고 전역에서의 this는 전역 객체 window를 가리킨다.

console.log(this) // window

 

- 일반 함수에서 this

일반 함수에서 this를 사용 시 전역 객체 window를 가리킨다.

하지만 strict mode일 경우 undefined가 바인딩된다.

메서드 내부에서 일반함수로 호출되면 this는 전역객체를 가리킨다.

ES6부터 객체 안의 함수 프로퍼티 축약형은 메서드이다. 이외에는 일반 함수이다.

function fn(){
    console.log(this) // window
}

function fn2(){
    'use strict' 
    console.log(this) // undefined
}

const obj = {
    foo(){
        function bar() {
        	console.log(this) // window
        }
    }
}

 

- 메서드에서 this 

메서드 내부에서 this를 호출하면 메서드를 호출한 객체를 가리킨다.

일반 함수로 호출된 모든 함수(중첩 함수, 콜백 함수) 내부의 this는 전역 객체가 바인딩된다.

var x = 'global' // window.x = 'global'

const obj = {
    x: 'local',
    foo(){
    	console.log(this) // {x: 'local', foo: f}
        console.log(this.x) // 100

        // 메서드 내에서 정의한 중첩 일반함수
        function bar(){
            console.log(this) // window
            console.log(this.x) // 'global'
        }
        bar()
        
        // 콜백 함수가 일반 함수로 호출되기 때문에 this는 window를 가르킨다.
        setTimeout(function(){
            console.log(this) // window
            console.log(this.x) // 'global'
        }, 100)
    },
}

obj.foo()

위의 setTimeout의 콜백함수 내부에서 this가 전역객체가 아닌 객체를 가리키려면 화살표 함수 또는 명시적으로 this 객체 전달(bind) 해주면 된다.

 

var x = 'global' // window.x = 'global'

const obj = {
    x: 'local',
    foo(){
    	// 콜백함수 화살표 함수로 호출
        setTimeout(()=>{
            console.log(this.x) // 'local'
        }, 1000)
        
        // 명시적으로 this 객체 전달
        setTimeout(function(){
			console.log(this.x) // 'local'
		}.bind(this),1000)
    },
}

obj.foo()

 

생성자 함수 this 호출 

- 생성자 함수가 생성할 인스턴스가 바인딩된다.

function Circle(radius){
    this.radius = radius
	this.getDiameter = function () {
        return 2 * this.radius
    }
}

const circle1 = new Circle(5)

console.log(circle1.getDiameter()) // 10