그 거시기(this)가 저 거시기(this)인가


(P Destiny) #1

옛날에 자신의 도끼를 우물에 빠트린 나무꾼이 있었습니다.

자신의 밥줄인 도끼가 빠져 우물앞에서 엉엉 울고 있는데

산신령이 우물에서 나와 나무꾼의 도끼와 금도끼를 보여주며

어느 거시기가 니 거시기냐 하고 물었습니다.

나무꾼은 솔직하게 자신의 도끼를 가르키며 저 거시기가 제 거시깁니다라고 말했습니다.

그런데 불행하게도 산신령은 백내장이여서 나무꾼이 가르킨 것 잘 보지 못하는 바람에

나무꾼이 금도끼를 자기 것이라라 한 줄 알았습니다.

그래서 나무꾼을 괘씸하게 여긴 산신령은 두 도끼를 모두 가지고 우물속으로 들어가버렸답니다.:joy:

이럿듯 일상 생활에서 거시기는 잘못 사용하면 큰 오해를 불러 일으킬 수 있습니다.

자바스크립트에서도 마찬가지라 생각합니다. this(거시기) 를 잘못 달라고 하면 v8산신령이 우물로 들어가버릴 지도 모릅니다.

그래서 자바스크립트의 그 거시기가 그 거시기인지 아닌지에 대해 공부해 볼려고 합니다.

제가 참고한 자료는 아래와 같습니다.


  1. https://youtu.be/aqgOxngcLDg
  2. https://youtu.be/v80yuod0ONk
  3. https://youtu.be/vvV-GZ6AMMY

거시기가 여러 거시기로 나뉘는 경우와 다른 객체의 거시기를 바꾸는 것은 함수를 통해 네가지 방법으로 이해할 수 있습니다.

먼저 나무꾼과 도끼가 있다고 가정합시다. 도끼를 휘두를때마다 도끼는 ‘거시기~’ 하고 소리를 지릅니다.

방법 1

첫번째 방법은 도끼가 혼자 휘둘러 지는 겁니다.

function 도끼를_휘두르다(){
    console.log(거시기);         //이때의 거시기는 global이 됩니다.
}
도끼를_휘두르다(); 

이때 거시기가 글로벌이 되는 이유는 첫번째로 다른 참조할 거시기가 없기 때문입니다.

그래서 자동으로 거시기는 윈도우가 됩니다.

이것만 가지고는 거시기가 왜 글로벌을 거시기로 잡는지 잘 이해아 안가는 것 같습니다.


방법 2

두번째 방법은 나무꾼이 도끼를 휘두르는 방법입니다.

var 나무꾼 = {};    //나무꾼이 나타났습니다.
나무꾼.도끼를_휘두르다 = function(){    //나무꾼이 도끼를 휘두를 능력을 얻었습니다.
    console.log(거시기);    //이때의 거시기는 나무꾼입니다!!!!
}

나무꾼.도끼를_휘두르다();

방법 1과는 상황이 많이 달라졌습니다. 도끼를 휘두루는 사람이 달라졌기 때문입니다.

이제 도끼가 거시기를 외칠때의 거시기는 바로 나무꾼이됩니다.

혼자서 휘둘러질때는 폴터가이스트 현상같은 것이여서 초자연적인 존재, 즉 글로벌한 존재가

도끼를 휘두르니 도끼가 말하는 거시기는 글로벌이고

나무꾼이 도끼를 쥐고 휘두루니, 이제 거시기는 나무꾼이 되는 것을 보니 거시기가 가르키는 것은

도끼자루를 쥔 넘인가 봅니다. 좀 이해가 가는군요.


방법 3

세번째 방법은 도끼가 스스로 새로(new) 도끼를 쥘 사람을 만드는 법입니다.

function 도끼를_휘두르다(){
    //var 거시기 = {}; new를 하면 주석처리한 부분과 똑같은 일이 벌어집니다!
    console.log(거시기);  //이때의 거시기는 위에 주석처리된 거시깁니다. 거시기는 완전히 빈 상태죠.
    //return 거시기;
}
new 도끼를_휘두르다(); // 똑같이 도끼를 휘두르는 것 같지만 새로이 도끼를 쥘 사람을 도끼가 만들어 냈습니다.

새로운 도끼를 쥘 사람은 new 를 할 경우, 굳이 밖에 나무꾼이 없어도 도끼 스스로가 만들어냅니다.

그렇기 때문에 이때의 거시기는 바로 도끼를 쥐고 있는 넘, 즉 도끼 스스로가 만들어낸 거시기가 도끼가 말하는 거시깁니다.


방법 4

네번째 방법은 지금까지와는 달리 도끼가 휘두를 놈을 밖에서 고를 수 있습니다.

도끼를 휘두를 사람은 반드시 나무꾼일 필요는 없습니다. 나무꾼이 휘두를 수도 있고 선녀가 나무꾼에게 휘두를 수도 있죠.

var 나무꾼 = {};     //나무꾼입니다.
나무꾼.생각 = "선녀를 겟했다 헤헷";
var 선녀 = {};     //선녑니다.
선녀.생각 = "내 옷 내놔 이 변태 ** 야!"

function 도끼를_휘두르다(){
    console.log(거시기.생각);
    console.log(거시기);
}

나무꾼과 선녀 모두 도끼를 휘두르는 방법은 바로 call을 쓰는 것입니다.

call은 함수객체가 가지고 있는 메서드로 누가 거시기가 될지를 결정할 수 있습니다.

call의 사용법은 바로 인자값에 거시기가 될 대상을 넣는 것입니다.

예를 들자면

도끼를_휘두르다.call(나무꾼); // 거시기는 나무꾼을 가르키고 "선녀를 겟했다 헷헷"을 출력합니다.

도끼를_휘두르다.call(선녀); //거시기는 선녀를 가르키고 "내 옷 내놔 이 변태 ** 야!"를 출력합니다.
//P.S 여성의 옷을 훔쳐가는 것은 범죄입니다.

출력값을 보시면 아시겠지만 똑같이 도끼를 휘둘렀는데 한 거시기는 나무꾼을, 다른 거시기는 선녀를 가르킵니다.

도끼 자루는 똑같은데 휘두른 사람은 바뀐거죠.(나무꾼은 저세상에 갔다고 예측해 봅니다.).


지난번에도 call, apply 그리고 bind에 대해서 글을 올린적이 있지만, 메서드에만 집중을 했지 거시기가 무엇인지에 대해서는

자세하게 공부를 하지 않았던 것 같습니다.

오늘 공부를 통해 거시기가 의미하는 것은 바로 도끼자루를 쥔사람을 뜻한 다는 것을 깨달았습니다.

주변에 거시기가 뭔지 몰라 고민하는 친구가 있는데 제가 쓴 예제를 보여주며

거시기는 거시기일 뿐이야

라고 잘 설명해 주어야 겠습니다. ㅎㅎ


Vue.js를 어떻게 사용하고 계신가요?
(윤종원) #2

와~ 완전 이해 빠르네요,!!!
좋은 글 감사합니다~~


(P Destiny) #3

ㅋㅋㅋㅋ 그렇다니 다행이네요


(이종은(Jong Lee)) #4

와우! 설명을 참 거시기하게 하셔서 참 거시기합니다. :+1: :grinning:
앞으로도 쭉 거시기 부탁할게요. :pray:


(P Destiny) #5

ㅋㅋㅋ 칭찬 감사합니다 ㅋㅋ 혹시 제가 올린 것들 중에 문제가 있는 내용이 있으면

지적해주시면 감사할것 같아요! 아직 js 입문이고 혼자 공부하는지라 제가 쓴 내용이

맞는지 틀린지 알 방법이 없어요 ㅠㅠ


(이종은(Jong Lee)) #6

또 다른 this관련 글이 있습니다. 참고 :slight_smile:


(P Destiny) #7

감사합니다!! 잘 읽었어요. (condition?obj.foo:obj.bar)()는
확실히 혼란스럽게 느껴집니다. 분명 obj의 foo에 레퍼런스를 걸었는데 obj에 접근할 수 없다니… 조심해야겠습니다 ㄷㄷ