[Javascript] this

★개발일기★ ㅣ 2022. 7. 14. 17:10

반응형

Javascript의 this

Javascript 에서의 this 는 우리가 흔히 처음접하게 되는 언어인 Java 의 this 와 사용법이 달라 혼동이 올 때가 있다.
Java 와 같은 객체지향 언어에서 this 는 class 로 생성된 인스턴트 자신이며, class 밖에서 사용 할 수 없다.
Javascript 의 this는 함수의 현재 실행 컨텍스트를 의미하는데 예제 코드를 통해 어떻게 다른지 살펴보자

1. 일반적인 함수

function defaultFunc() {
	console.log(this) // window or global    
}

이 함수의 실행 컨텍스트는 전역 객체이므로, 브라우저 환경에서는 window , Node 환경에서는 global 객체가 될 것이다.

2. strict 모드에서의 함수 실행

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

3. 내부 함수

const obj = {
	fruit: "apple",
	test: function() {
    	console.log(this) // obj
        function innerFunction() {
        	console.log(this) // window or global
        }
        innerFunction()
    }
}

test 의 실행 컨텍스트는 obj 이므로 this 는 obj 이며, test 내부에 있는 innerFunction 은 메소드가 아니고 함수 실행 이기때문에 컨텍스트는 window or global 이 된다.

4. 메소드

const methodTest = {
	call: function() {
    	console.log(this === methodTest) // true
    }
}

methodTest.call()

 call 메소드의 실행 컨텍스트 객체인 methodTest 가 this 가 된다.
 메소드와 함수실행을 구분하는 방법은 메소드는 참조한다는 기호인 콤마가 있고 함수실행은 없다.   

someMethod.call() // method
someFunction() // function

   4-1 주의

const methodTest = {
	fruit: "apple",
    run: function() {
    	console.log(this.fruit)
    }
}

const runTest = methodTest.run

runTest()

위와 비슷하지만 methodTest 의 run 이라는 메소드를 runTest 라는 변수에 담아 호출하였을때 this 는 어떻게 될까?
methodTest 가 메소드 일지라도 runTest() 는 함수 호출이기 때문에 this 는 전역객체가 되고 전역객체에는 fruit 가 없기 때문에 undefined 가 콘솔에 찍힌다.

5. 생성자

class Person {
	constructor() {    
		this.userName = "John"
        	console.log(this) // Person{}    
    }    
}

const instance = new Person()
console.log(instance.userName) // "John"

new Person() 은 생성자 실행이다. 이 때 컨텍스트는 Person 의 인스턴스이다.

  5-1 주의

function Person() {
	this.userName = "Jone"
    return this
}

const instance = Person()
console.log(instance.userName)

몇몇 함수는 함수를 실행해도 인스턴스를 반환하는 함수가 있다.
위의 Person 함수는 함수 실행을 해도 객체가 반환 된다.
생성자 실행으로 반환되는 this 는 Person 인스턴스이지만, 함수 실행으로 반환되는 this 는 전역 오브젝트이다.
그래서 "Jone" 이라는 문자열을 this.userName 에 할당했는데, window.userName = "Jone" 을 한 것이니 주의하자.
이를 조금 쉽게 해결하려면 instanceof 키워드를 사용하면 되는데,  

function Person() {
	if(!(this instanceof Person)){
    	throw Error("Incorrect invocation" , { cause : "해당 인스턴스가 아닙니다" })
    }
	this.userName = "Jone"
    return this	
}

const instance = Person()
console.log(instance.userName)

해당 키워드로 this가 Person 타입의 객체가 맞는지 방어코드를 추가하면 막을 수 있다.

반응형