프론트엔드/Javascript, TS

javascript의 this는 대체 무엇인가? ①편

데브힐러 2020. 2. 13. 22:55
반응형

자바스크립트를 심층도 있게 다룬 You don't know js라는 책이 있다. 한국에도 번역본이 존재한다. 현재 해외 거주중이기에 높은 배송비를 물어가며 사기가 쉽지 않다. 저자가 친절하게도 본문(영어)을 전부 git hub저장소에 공개해놓았다.

 

현재 개발할 때 주 사용 언어가 js이다. node.js 나 클라이언트쪽 코딩을 하며 수많은 에러를 만났다. 당연히 쓰는 비동기 처리, this, scope&closure 등등 코딩에는 능숙해졌지만 원리나 개념에 대해 명확한 나만의 언어로 표현하기가 힘들다는 것을 알게되었다. 이를 계기로 You don't know js를 단원별로 공부하며 정리해 보았다.

 

 


Object 단원- this란 무엇인가?

 

this is a binding made for each function invocation, based entirely on its call-site (how the function is called).

this는 각 함수 호출을 위해 만들어진 바인딩이며 함수의 call-site에 전적으로 기반한다. 

 

이를 위해 call-site와 call-stack 의 구분이 필요하다.

 

 

Finding the call-site is generally: "go locate where a function is called from".

call-site는 함수가 호출되는 곳이다.

 

What's important is to think about the call-stack (the stack of functions that have been called to get us to the current moment in execution). The call-site we care about is in the invocation before the currently executing function.

영문을 해석하면 -

*call-stack은 현재 함수를 실행하고자 호출된 함수가 들어 있는 스택이다. 

call-site는 가장 최근의 함수가 실행되는 동안 호출 상태에 있다. 

 


 

 

※ 여기서 함수의 호출을 callinvocation 두 단어를 사용하여 표현하고 있다. 두 단어의 의미는 같다. 그러나 엄밀히 말해 call은 프로그래머가 직접 함수를 호출 하는 것 invocation은 생성자 호출 등을 통해 자동으로 호출 되는 경우를 말한다. (출처: quora)

 


struct s
{
  int a,b,s;
 
  s()
  {
    a=2;
    b=3;
  }
 
  void sum()
  {
    s=a+b;
  }
};
 
void main()
{
  struct s obj; //line 1
  obj.sum(); // line 2
}

C++코드

* line1이 실행되면 구조체 s의 객체인 obj가 만들어진다. 동시에 생성자(constructor)가 불린다. 이 때 생성자

s()함수가 호출(invoked)된다.

 

*line2가 실행되면 생성된 객체 obj 안에 있는 sum(); 메소드 함수를 호출(called)한다. 


 

js코드는 위에서부터 읽힌다. 함수의 호출부분이 나올 때마다 call-stack(호출스택)에 쌓이고 쌓인 반대방향으로 실행된다.(가장 나중에 들어온 함수부터) 함수의 실행이 완료되면 call-stack에서 사라진다. 

이를 간단한 코드를 통해 풀이하고 있다. 직접 크롬에서 디버그 해보면 이해가 빠르다.

 


function baz() {
    // call-stack is: `baz`
    // so, our call-site is in the global scope

    console.log( "baz" );
    bar(); // <-- call-site for `bar`
}

function bar() {
    // call-stack is: `baz` -> `bar`
    // so, our call-site is in `baz`

    console.log( "bar" );
    foo(); // <-- call-site for `foo`
}

function foo() {
    // call-stack is: `baz` -> `bar` -> `foo`
    // so, our call-site is in `bar`

    console.log( "foo" );
}

baz(); // <-- call-site for `baz`

global scope에서 baz()를 호출한다. 따라서 call-site는 전역(global-scope)이다.

baz()함수는 bar()를 호출하므로 bar()를 부르는 call-site는 baz()함수 내부이다.

* call-stack

맨 처음 global-scope baz를 호출할 때

anonymous의 콜스택이 생긴다. 호출 순서로 마지막 foo()까지 쌓이게 된다. 

 

 

* console

콘솔창에는 당연히 baz부터 실행되므로 왼쪽과 같은 순서로 나타나며

함수의 실행이 끝나면 call-stack에서 사라진다.

 

 

 

다음은 본격적으로 this의 주 역할인 바인딩(binding)에대해서 알아보겠다.

 

출처 : https://www.quora.com/What-is-the-difference-between-call-and-invoke

 

What is the difference between 'call' and 'invoke'?

Answer (1 of 4): Code wise: [code]struct s { int a,b,s; s() { a=2; b=3; } void sum() { s=a+b; } }; void main() { struct s obj; //line 1 obj.sum(); // line 2 } [/code]Here, when line 1 is executed, the function (constructor, i.e. s) is invoked. When line 2

www.quora.com

https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/objects-classes/ch2.md

 

getify/You-Dont-Know-JS

A book series on JavaScript. @YDKJS on twitter. Contribute to getify/You-Dont-Know-JS development by creating an account on GitHub.

github.com

 

 

반응형