brunch

You can make anything
by writing

C.S.Lewis

by zwoo May 11. 2021

자바스크립트, this, 호출, 객체, 바인딩

각각 무슨 말인지 한번 알아보자

자바스크립트에서 this 는 호출하는 객체에 바인딩된다.

이 문장을 이해하는 데에는 this, 호출하다, 객체, 바인딩 이라는 단어에 대한 이해가 먼저 필요하다.



this 는 함수가 실행되는 공간을 가리킨다.


실행컨텍스트, 혹은 스코프를 공간에 비유하는 것은 프로그래밍 언어의 관점에서는 부자연스럽지만, this 의 움직임을 상상하는 데에는 꽤 도움이 된다. 나의 경우에는 어떤 개념을 공부할 때 머릿속으로 추상적인 이미지나마 그려내지 못하면 이해도 암기도 할 수가 없어서 엄청 애를 먹기 때문에, 어떻게든 이미지화를 하려고 노력하는 편이다. 자바스크립트는 컴파일 언어가 아니기 때문에, 함수가 선언되는 시점과 호출되는 시점이 반드시 일치하지는 않는다. 컴파일 언어의 자세한 특징에 대해서는 모르기 때문에 이 글에서 설명하지 않는다. 중요한 것은 자바스크립트라는 언어는 함수의 선언시점보다 호출시점에 더 많은 관심이 있다는 것이다. 어느 파일의 몇번째 라인에서 eat 이라는 함수를 호출( eat() 또는 eat.apply() 또는 eat.call() 과 같은 방식으로 호출함 ) 하면, 그 함수를 위한 실행컨텍스트라는 공간이 생긴다. this는 바로 이 함수 호출로 인해 생겨난 새로운 공간을 가리키고, 이 제한된 영역 (스코프) 안에서만 사용할 수 있는 지역변수들을 가지게 된다.


실행컨텍스트는 처음 파일이 생성될 때, 그리고 함수가 호출될 때마다 이전에 만들어진 실행컨텍스트 위에 차곡차곡 스택 -콜스택- 으로 쌓인다. 파일이 생성될 때에는 가장 먼저 전역 컨텍스트가 쌓이고, 그 위에 호출되는 함수의 순서대로 새로운 실행컨텍스트들이 쌓인다. 각각의 함수가 return 될때, 실행컨텍스트는 사라진다. 이는 메모리 낭비를 막기 위함이라고 한다. 앞서 말했듯 실행컨텍스트 안에는 지역변수들이 있는데,  먼저 쌓여있던 실행컨텍스트의 변수들은 그 위에 쌓인 실행컨텍스트 입장에서는 전역변수가 되기 때문에 자유롭게 접근할 수 있다.  함수를 실행하여 만들어진 이 실행컨텍스트들은 메모리 공간 위에 누적되기 때문에, 이렇게 계속 컨텍스트를 쌓아 올리면 메모리에 부담을 준다. 함수는 자기 역할을 다한 후 리턴해주어야 한다. 그래야 불필요한 메모리 낭비가 없다.



함수는 객체이며, 함수를 호출하면 바로 그 함수 객체가 실행된다.


함수는 객체이다. 함수는 메소드들을 자신의 속성으로 가지고 있다. 나는 객체라는 말을 들으면 본능적으로,


{ }


이렇게 생긴 오브젝트가 떠오르기 때문에 함수가 객체라는 말이 낯설었는데, 단순히 생각하자면 함수도 속성들을 가지고 있기 때문에 객체라고 할 수 있다. 함수가 가진 대표적인 메소드 속성으로 apply, call 이 있다.

eat.apply ,  eat.call 은 eat 함수를 호출하는 메소드이다.


 

바인딩이란, this 가 가리킬 실행컨텍스트를 특정한 함수객체로 확정하는 것이다.


this는 전역컨텍스트만 있을 때에는 전역객체를 가리킨다. 함수가 호출되어 실행되면 전역객체 위에 새로운 실행컨텍스트가 쌓이고, this 는 이 새로운 실행컨텍스트를 가리키도록 정해진다. 즉, 방금 실행된 함수객체에 바인딩된다.



호출시점에 상관 없이 this를 명시적으로 고정하는 방법이 있는데, 바로 apply 와 call, bind 이다.


apply 와 call 은 기본적으로 함수호출 메서드이다. 두 메소드 모두 실행컨텍스트를 첫번째 인자로 넘겨주기로 규칙이 정해져있다. this 는 바로 이 첫번째 인자로 넘겨주는 객체에 바인딩된다. 만약 첫번째 인자가 null 인 경우 자동으로 전역객체에 바인딩된다. bind 메소드는 실행컨텍스트 바인딩을 한 새로운 함수를 만드는 함수이다. bind 메소드는 함수 호출을 하지는 않는다.





Photo by Erlend Ekseth on Unsplash



참고링크


Function.apply() : https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function/apply


Function.call() : https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function/call




TMI 1.

놀랍게도, 브런치에서는 한달동안 글을 쓰지 않으면 엄청 귀여운 팝업알림이 뜬다..! 도도한 느낌의 어플에서 T_T... 이런 귀여운 이모티콘을 보낼 줄은 몰랐어서 왠지 미안해져서 글을 써야겠다고 마음 먹었다.


TMI 2.

꾸준히 글쓰는 것이 벅차고 힘에 부친다. 글에 담아낼 만한 지식이 뭉치기도 전에 다른 걸 숙지해야 하는 나날의 연속이다. 나는 학생이 아니고, 해야할 업무에 필요한 지식은 아주 많기 때문에 공부한 내용들을 뭉칠 새 없이 여기저기 메모해놓기 바쁘다.


솔직히 말해서, 맨 처음에 리액트를 공부할때 프로그래밍에 두가지 길이 있다고 생각했다. 하나는 깊은 길, 하나는 얕은 길. 나는 진심으로 두개가 나눠져있다고 생각했고 나중에 한 10년 정도 일하면 합쳐질 가능성도 있다고 생각했는데, 그래서 천천히 공부하다가 언젠가 꽤 많이 알게 되겠지 - 하는 태평한 생각을 하고 있었는데 요즘 숨막히게 공부하면서 드는 생각은 길은 나눠져있지 않고 좀더 열심히 뛰지 않으면 조만간 내 자리가 없어질 수도 있다는 위기감이다.


TMI 3.

나는 한번 어떤 직업을 가지려고 했다가 실패했었고, 거기에 꽤 올인했었기 때문에 많이 허전했다. 그래서 그 다음에 직업을 선택할 때에는 아무리 재미있더라도 올인하지 않으려고 마음을 먹었었다. 어떡하지. 지금은 매일같이 공부하는 게 싫지는 않은데, 과연 계속 즐겁게 버텨낼 수 있을까?

        



이전 07화 자바스크립트의 함수는 어디서 오는 걸까?
brunch book
$magazine.title

현재 글은 이 브런치북에
소속되어 있습니다.

작품 선택

키워드 선택 0 / 3 0

댓글여부

afliean
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari