본문 바로가기
지금, 개발하기/Javascript

javascript] this 바인딩 파헤치기

by Seaco :) 2023. 1. 13.

Javascript의 this 바인딩은 다른 언어(C#, C++, JAVA, .. )와 달리 동적으로 결정됩니다. 그래서 조금은 헷갈릴 수 있는데 결론부터 말하자만 ‘Javascript의 This’는 ‘호출한 놈’을 의미합니다. 먼저 기본값(?)으로 쓰이는 ‘호출하는 놈’의 의미를 알아보고, 그 다음에 예외인 경우 어떻게 동적으로 바인딩되는지 알아보겠습니다.

 

Javascript에서 this란?

  • this는 '호출한 놈'을 의미합니다.
    만약 '호출한 놈'이 없으면,  기본값인 '전역객체(window)'를 출력합니다.
  • 예외 사항: ①전역스코프에서 this ②strict mode ③화살표함수

 

1. this는 호출한 놈
function testThis(){
	console.log(this)
};

const student1 = {
    name: 'mike',
    age: 20,
    printStudent: testThis
}

const student2 = {
    name: 'jerret',
    age: 30,
    printStudent: testThis
}

const student3 = {
    name: 'cole',
    age: 25,
    printStudent: testThis
}

testThis();                     // 호출한 놈이 없는 경우: window 객체
student1.printStudent();        // {name: 'mike', age: 20, printStudent: ƒ}
student2.printStudent();        // {name: 'jerret', age: 30, printStudent: ƒ}
student3.printStudent();        // {name: 'cole', age: 25, printStudent: ƒ}

 

호출하는 놈이 없다면?

whoIsIt 변수에 student.printStudent 함수를 담았지만, 막상 whoIsIt 함수를 호출할 때는 호출하는 놈이 정해져있지 않습니다. 이럴 경우 javascript는 window 객체를 출력합니다.

const student = {
    name: 'mike',
    age: 25,
    printStudent: function() {
        console.log(this);      
    }
};

student.printStudent();     // {name: 'mike', age: 25, printStudent: ƒ}

let whoIsIt = student.printStudent;   
whoIsIt();                  // window 객체

 

호출하는 놈을 지정해주고 싶다면?

읭? window객체? 사실 나는 student객체를 지정해주고 싶었는데 말이죠... 답답하죠? 이런 경우를 대비해서 javascript는 bind함수를 사용지원합니다. bindWhoIsIt함수처럼 bind함수에 바인딩을 원하는 객체를 함께 넣어주면 내가 원하는 결과가 나옵니다. (또는 잠시 뒤에 나오는 화살표 함수를 사용하면 됩니다.)

const student = {
    name: 'mike',
    age: 25,
    printStudent: function() {
        console.log(this);      
    }
};

student.printStudent();     // {name: 'mike', age: 25, printStudent: ƒ}

let whoIsIt = student.printStudent;   
whoIsIt();                  // window 객체

let bindWhoIsIt = whoIsIt.bind(student);
bindWhoIsIt();              // {name: 'mike', age: 25, printStudent: ƒ}

 

2. 예외

1. 전역스코프에서 this
: 콘솔창에서 this를 출력하면 window객체가 출력됩니다. (

// 웹 브라우저
consol.log(this)   // window

 2. strict mode
: 엄격모드를 선언하지 않으면 함수 내부에서 this는 window 객체가 출력됩니다.

function printStudent(){
    console.log(this);      
}
printStudent();            // window 객체

그러나 엄격모드에서는 함수라는 스코프 내에 this가 없기때문에 undefined가 나옵니다. 

use strict'

function printStudent(){
    console.log(this);     
}
printStudent();            // undefined

3. 화살표 함수
:
Arrow 함수는 일반함수와 달리 렉시컬 환경에서의 this를 기억합니다. 그래서 화살표 함수 자체에는 this가 없지만, 화살표 함수는 자신을 포함하고 있는 스코프 중 제일 근접한 상취 스코프의 this를 정적으로 바인딩합니다. 이때문에 bind함수를 이용해서 억지로 원하는 객체를 바인딩해줄 필요가 없죠. 이러한 편리성으로 저도 화살표함수를 많이 사용합니다.
상위 함수 스코프를 가지는 arrowTest2함수를 이용해서 예제를 보여드리겠습니다.

일반함수 arrowTest2는 호출 시 아무 값도 출력되지 않습니다.

const student = {
    name: 'Jane',
    age: 33,
    arrowTest: function() {
        const arrowTest2 = function () {
            console.log(this.name)
        }
        arrowTest2();
    }
}

student.arrowTest();

하지만 화살표함수 arrowTest2는 호출 시 상위에 있는 객체를 가리킵니다.

const student = {
    name: 'Jane',
    age: 33,
    arrowTest: function() {
        const arrowTest2 = () => {
            console.log(this.name)              // Jane
        }
        arrowTest2();
    }
}

student.arrowTest();