Little Jay

[JS] Javascript에서의 this 규칙 본문

FrontEnd/Front End Interview Handbook

[JS] Javascript에서의 this 규칙

Jay, Lee 2022. 12. 28. 22:30

질문출처: https://www.frontendinterviewhandbook.com/javascript-questions#explain-how-this-works-in-javascript

 

JavaScript trivia questions in front end interviews | Front End Interview Handbook

Answers to Front-end Job Interview Questions - JS Questions. Pull requests for suggestions and corrections are welcome!

www.frontendinterviewhandbook.com

Javascript "this"에 대하여

 사실 자바스크립트에서 "this"라는 키워드를 간단하게 정의할 수는 없다. 이 카워드는 자바스크립트에 있어서 가장 헷갈리는 컨셉이기 때문이다. "this" 키워드에 대한 간단한 정의는 "this"의 value는 어떻게 함수가 호출되는지에 따라 다르다. "this"에 대한 많은 설명을 읽어보았는데, https://medium.com/@arnav_aggarwal 이 사람이 정리한 글이 제일 명확하다고 생각한다. this에 대한 규칙은 다음과 같다.

1. 만약 "new" 키워드가 함수 호출시에 사용이 된다면, 함수 내의 "this"는 새로운 객체이다.

function ConstructorExample() {
    console.log(this);
    this.value = 10;
    console.log(this);
}
new ConstructorExample();

이 예시를 보자. 코드를 실행시키면, 첫 번째로 console.log(this)는 아무것도 return되지 않는다. 반면, 두 번째 console.log(this)는 명백히 value라는 key를 가지는 새로운 객체가 생성이 된다. 

2. apply, call, bind가 함수 호출시 사용이 된다면, 함수 내에 있는 "this"는 argument이다.

function fn() {
    console.log(this);
}
let obj = {
    value: 5
};
let boundFn = fn.bind(obj);

boundFn(); 
fn.call(obj);
fn.apply(obj);

 위 코드의 실행결과는 모두 { value: 5 } 이다. 이처럼 this는 단순히 object가 되는 것을 확인할 수 있다. 

3. 함수가 메소드로서 호출이 된다면( "."을 통해 호출) "this"는 함수의 부분중 하나인 객체이다. 다시말해서 "."이 함수의 왼쪽에 있다면 this는 "."왼쪽에 있는 객체이다. 

let obj = {
    value: 5,
    printThis: function() {
        console.log(this);
    }
};
obj.printThis();

 위 코드의 결과는 { value: 5, printThis: f } 이다. 여기서 f는 코드 블록의 기능을 상징한다. 어찌 보면 당연하다고 할 수 있는데 this는 obj 자신을 가리키게 된다. 

4. 함수가 "free function"으로 호출되는 경우, 다시말해 아무런 제시된 조건 없이 호출이 된다면 이는 전역객체이며, 브라우저에서는 Window객체이다. 

function fn() {
    console.log(this);
}

fn();

 실제로 출력 결과는 console.log(window) 와 같다. 사실 이것은 3번째 규칙과 동치이다. 단순히 function을 선언했냐 안했냐의 차이가 있을 뿐, JS는 window에서 돌아감으로 window object 그 자신이 되는 것이다. 따라서 console.log(fn === windonw.fn)의 결과는 true가 나온다.

5. 위에 언급한 규칙 중 여러 개가 적용이 된다면 더 놓은 규칙이 우선순위가 되고 이를 적용한다.

let obj1 = {
    value: 'hi',
    print: function() {
        console.log(this);
    },
};
let obj2 = { value: 17 };

new obj1.print();

 이 코드를 보면 1번과 3번룰이 적용이 되어있다. 이 코드의 결과는 {} 이다. 이를 통해 1번 규칙이 우선시 된다는 것을 볼 수 있다. 

6. ES2015에서 부터 함수가 화살표 함수인 경우 위의 모든 규칙을 무시하고, 생성될 때 주변 범위의 this 값을 받는다. 

const obj = {
    value: 'abc',
    createArrowFn: function() {
        return () => console.log(this);
    }
};
const arrowFn = obj.createArrowFn();
arrowFn();

 이 코드의 결과는 { value: 'abc', createArrowFn: f } 이다. 3번째 규칙으로 돌아가서 우리가 obj.createArrowFn()을 했을 때 createArrowFn의 내부의 this는 obj 일 것이다. 이를 "."으로 호출하고 있기 때문이다. obj는 따라서 arrowFn에서 this에 bound되는 것이다. 만약 전역적인 범위에서 화살표 함수를 만든다면 이는 window 객체가 될 것이다. 

 

Comments