[Javascript Basic] - What is 'this' (1)

제리·2021년 5월 15일
0

Javascript Basic

목록 보기
1/1

자바스크립트를 공부하다보면 필연적으로 this라는 키워드를 마주치게된다.
하지만 this가 무엇을 뜻하는지 파악하기 아리송송할때가 있다.

왜 그런걸까?

자바스크립트를 배우기 이전에 C++과 JAVA를 먼저 배웠다면, 더 헷갈리기 쉽다.
왜냐하면 이때의 this는 클래스를 사용하여 새로 생성된 객체 자기자신을 가르킨다고 암기했기 때문이다.
따라서 C++과 JAVA에서의 this는 정적인 성격을 띄고있다.

하지만 자바스크립트에서의 this는 다르다.
자바스크립트의 this는 동적인 성격을 갖고있다.
동적이라는 말은 함수의 호출시점에서 this가 결정되므로 값이 고정되어 있지 않다는 뜻이다.

this를 쉽게 이해하기 위해선 기존에 배웠던 this는 잠시 제쳐두고 자바스크립트 특유의 유연한 사고방식으로 접근할 필요가 있다.

this의 관한 여러 포스트들을 읽고 여러 실험을 거쳤을때 가장 쉽게 this를 이해할 수 있는 결론은 이렇다.

this는 함수를 소유한 객체를 가르킨다.

말로 하는것보다 코드를 통해 확인하는것이 더욱 이해가 잘될것이다.

function Person(name,age){
    this.name = name
    this.age = age
    console.log(this)
}

Person('jary',100)

해당 코드를 실행해보면 this가 나타내는 값이 window라는것을 확인할 수 있을것이다.
엥?? 갑자기 웬 window? Person 함수와 window가 무슨 관계가 있다는거지? 싶을수도있다.
결론적으로 Personwindow객체에 포함되어 있다.
왜냐하면 브라우저 환경에서 전역은 window객체를 뜻하기 때문이다.
따라서 전역 변수, 전역 함수, 전역 객체 모두 window가 이를 소유하게된다.
위 상황에서 Person은 전역 함수이기 때문에 window객체가 이를 소유하게된다.
(window.가 생략되었다고 볼 수 있다.)

다음 코드를 실행해서 다시 한번 확인해보자.

var name = 'jary' // 전역변수 선언 및 정의
console.log(name) // jary
console.log(window.name) // jary

같은 값을 출력한다.

자, 그러면 this가 함수를 소유한 객체를 가르킨다고 했으니, Person함수의 소유권을 변경하고 다시 테스트해보자.

var language = '아직 없음' // 전역 변수이므로 window.language로 접근이 가능하다.

function Person(){
    console.log('제가 사용하는 언어는 ' + this.language + '입니다')
}

var Korea = {
  language:'한국어'
}

Korea.person = Person

console.log(Person()) // 제가 사용하는 언어는 아직 없음입니다.
console.log(Korea.person()) //  제가 사용하는 언어는 한국어입니다.

var America = {
  language:'영어'
}

America.person = Person
console.log(America.person()) //  제가 사용하는 언어는 영어입니다.


America.person = Korea.person
console.log(America.person()) //  제가 사용하는 언어는 영어입니다.

첫번째 출력에서의 Person함수를 소유한 객체가 window이다. 따라서 thiswindow를 가르키기 때문에 language의 값이 아직없음이 출력되었다.

두번째 출력에서는 Person함수를 Korea객체의 person에 할당하도록 하였고 person함수 호출하는 시점에서 함수를 소유하는 객체가 Korea이기 때문에 한국어를 출력한다.

세번째 출력에서는 두번째와 마찬가지로 America객체의 person에 할당하도록 하였고 person함수를 호출하는 시점에서 함수를 소유하는 객체가 America이기 때문에 영어를 출력한다.

네번째 출력에서는 America person에 Korea person함수를 할당했다. 그래도 person함수를 호출하는 시점에서 America객체가 소유하므로 this.language는 영어를 가르키게 된다.

이해가 되었다면, 다음 예제의 출력을 예측해보자.

function whoAmI(){
   console.log(this.name)
}

var a = {
    name:"a",
    b:{
        name:"b",
        c:{
            name:"c"
        }
    }
}

console.log(whoAmI())

a.who = whoAmI

console.log(a.who())

a.b.c.who = whoAmI

console.log(a.b.c.who())

a.b.who = a.b.c.who

console.log(a.b.who())

다음에는 bind, apply, call함수를 이용하여 this를 직접 변경하는 방법에 대해 알아보자.

profile
흐릿한 잉크가 뚜렷한 기억보다 낫다

0개의 댓글