본문 바로가기

JavaScript/Basic-Javascript

자바스크립트 정리하며 배우기[22] - This[1] : 함수와 this, this 의 개념, this 와 that

안녕하세요. Tay 입니다.

자바스크립트에서 this 개념은 매우 중요합니다. 자바스크립트의 this 는 타 언어와 개념이 조금 다릅니다.

어떻게 보면 this 는 실행되는 흐름? 문맥? 이라고 볼 수 있습니다.

 

this

  • 함수 내부로 전달되어 호출한 객체를 참조하는 this 인자
  • 호출 패턴에 따라서 다른 바인딩

 

호출 패턴에 따른 바인딩

1. 객체의 메서드 호출 할때 this 바인딩

1) index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script src="obj_method.js"></script>
  </body>
</html>

 

2) obj_method.js

obj_method

let myObj = {
  name: "kim",
  sayName: function() {
    console.log(this.name);
  }
};

let otherObj = {
  name: "lee"
};

otherObj.sayName = myObj.sayName;

myObj.sayName();
otherObj.sayName();
  1. 객체 myObj 에는 메서드 sayName 이 있다.
  2. 객체 otherObj.sayName 메서드를 생성하고, myObj.sayName 메서드를 할당했다.
  3. myObj.sayName 과 otherObj.sayName 메서드의 출력 값을 확인해보자.  

 

Github Commit

 

결과 : 

각각의 sayName 메서드는 객체.name 프로퍼티 값을 출력했다.

이때 this 는 해당 메서드를 호출한 객체로 바인딩 된다.

 

 

2. 함수를 호출할 때 this 바인딩

1) index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <!-- <script src="obj_method.js"></script> -->
    <script src="func.js"></script>
  </body>
</html>

 

2) func.js

func.js

var firstNm = "geuntae";

console.log(firstNm);
console.log(window.firstNm);

let sayFullNm = () => console.log(`kim${this.firstNm}`);

sayFullNm();
  1. 전역변수 firstNm 을 선언한다. (전역변수는 전역객체의 프로퍼티다.)
  2. 전역 객체 window 안에 firstNm 을 콘솔로 찍는다.
  3. sayFullNm 함수 안에 this 는 어떤 것을 가르키는지 확인해본다.

 

Github Commit

 

결과 :

func.js 결과

firstNm 이 두번 출력 되고, fullNm 이 한번 출력됐다.

이유는 sayFullNm 함수 내부의 this 는 전역객체로 바인딩 되었고, 전역객체 window 는 firstNm 프로퍼티가 되어 출력된 것이다. 즉, this 는 전역객체 window 를 바라보고있다.

 

해설 :

겉에 window 전역객체가 있다고 생각하면 이해가 편하다.

전역변수는 전역객체의 프로퍼티가 되고, this 는 전역객체를 바라보기때문에 window 를 가르킨다.

* 그림이 엉망이지만, 내용에 집중해주세요.

 

3. 내부 함수를 호출할 때 this 바인딩(this 와 that)

1) index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <!-- <script src="obj_method.js"></script> -->
    <!-- <script src="func.js"></script> -->
    <script src="inner_func.js"></script>
  </body>
</html>

 

2) inner_func.js

inner_func.js

var value = 100;

let myObj = {
  value: 1,
  func1: function() {
    this.value += 1;
    console.log(`func1() called. this.value : ${this.value}`);

    func2 = function() {
      this.value += 1;
      console.log(`func2() called. this.value : ${this.value}`);

      func3 = function() {
        this.value += 1;
        console.log(`func3() called. this.value : ${this.value}`);
      };

      func3();
    };

    func2();
  }
};

myObj.func1();
  1. 전역변수 value 를 선언한다.
  2. myObj.func1 메서드를 실행한다.
  3. func2 내부 함수 호출을 실행한다.
  4. func3 내부 함수 호출을 실행한다.

위 내용을 보고 결과가 어떻게 되는지 생각해보자.

 

Github Commit

 

결과 :

결과가 2, 3, 4 가 아닌 2, 101, 102 로 출력됐다. 그 이유가 뭔지 알아보자.

 

이유 :

myObj.func1 은 메서드 호출이었다.

그렇기때문에 func1 을 호출한 객체로 this 가 바인딩 된다.

 

중요!!

하지만 func2, func3 는 내부 함수 호출이었다.

함수 호출에서의 this 바인딩 특성은 내부 함수를 호출했을 경우에도 그대로 적용된다.

 

That

부모 함수의 this 를 내부 함수가 접근 가능하도록 저장해주는 변수

※ 꼭 이름이 that 이 아니어도 된다. 다만, 암묵적인 룰이다.

 

위 inner_func 의 코드를 that 으로 수정해서 원하는 2, 3, 4 가 출력되도록 변경해보자.

변경 전 변경 후
var value = 100;

let myObj = {
  value: 1,
  func1: function() {
    var that = this;

    this.value += 1;
    console.log(`func1() called. this.value : ${this.value}`);

    func2 = function() {
      that.value += 1;
      console.log(`func2() called. this.value : ${that.value}`);

      func3 = function() {
        that.value += 1;
        console.log(`func3() called. this.value : ${that.value}`);
      };

      func3();
    };

    func2();
  }
};

myObj.func1();

func1 메서드 호출 이후, func1의 this 를 that에 삽입하여 that을 사용했다.

 

Github Commit

 

결과 :

내부 함수에서 myObj 의 value 값을 올리는 것을 확인할 수 있다.

 

정리!!

  • 객체 메서드 호출시 this 는 해당 매서드를 호출한 객체로 바인딩 된다.
  • 함수 호출시 전역 객체로 this 바인딩 된다.
  • 내부 함수 호출시 전역 객체로 this 바인딩 된다.
  • 부모 함수의 this 를 저장하는 관례는 that 이다.

 

 

이 글은 개인 공부목적으로 작성되었습니다.

정보가 잘못 되거나 궁금한 사항은 댓글로 부탁드립니다!! 읽어주셔서 감사합니다.