[JS] 자바스크립트의 this

baegyeong·2024년 7월 14일

Java Script

목록 보기
4/9
post-thumbnail

코어자바스크립트 ch3. this를 읽고 제 생각과 함께 정리한 내용입니다.


실행컨텍스트와 this를 함께 톺아보기

this는 실행컨텍스트가 생성될 때 함께 결정된다.

그렇다면 교재의 코드를 실행컨텍스트의 생성과 this를 중점으로 살펴보자.

  • 실행컨텍스트의 ThisBinding: 식별자가 바라봐야 할 대상 객체
  • 메서드의 내부함수에서의 실행컨텍스트와 this
// --------------------------------- (1)
var obj1 = {
  outer: function () {
    console.log(this);
    var innerFunc = function () {
      console.log(this);
    };
    innerFunc(); // ---------------- (3)

    var obj2 = {
      innerMethod: innerFunc,
    };
    obj2.innerMethod(); // --------- (4)
  },
};
obj1.outer(); // ------------------- (2)

(1) 시작

  • 전역 컨텍스트는 environmentRecord에 obj1 식별자를 저장한다.
  • 선언 시점이 없으므로 전역 컨텍스트의 outerEnvironmentReference에는 아무것도 담기지 않는다.
  • this는 전역객체를 가리킨다.

(2) obj1.outer() 함수 호출

  • 이 시점에서는 outer 실행 컨텍스트의 environmentRecord에 innerFunc와 obj2 식별자를 저장한다.
  • outerEnvironmentRecord는 outer를 선언될 당시의 LexicalEnvironment를 담는다. (obj1)
  • this에는 obj1이 바인딩된다.

(3) innerFunc() 함수 호출

  • outer 함수 내부에서 innerFunc()를 호출한다.
  • 식별자는 없으므로 environmentRecord에는 아무런 값도 담기지 않는다.
  • outerEnvironmentReference에는 outer()의 LexicalEnvironment가 담긴다.
  • 메서드로서가 아닌 함수로 호출했으므로 this는 전역객체를 가리킨다.

(4) innerFunc() 종료 및 obj2.innerMethod() 실행

  • innerFunc()는 콜스택에서 빠져나가고, obj2.innerMethod()를 호출하여 실행컨텍스트가 생성된다.
  • outerEnvironmentReference에는 outer()의 LexicalEnvironment가 담긴다.
  • 메서드로서 호출했으므로 this에는 obj2가 바인딩 된다.

내부함수에서 this 우회하기

  • ES5에서는 호출 당시 주변 환경의 this를 그대로 상속 받기 위한 방법으로 변수를 사용하는 것이 있다.
  • 실제로 작동방식은 어떻게 될까?
    • ch1의 방식처럼 this 객체를 ‘참조’한다.
    • 즉 변수를 사용하는 것은 주변 환경을 동일하게 ‘참조’하는 방식으로 우회하는 방법이다.
      var obj1 = {
        outer: function () {
          console.log(this);
          var innerFunc1 = function () {
            console.log(this);
          };
          innerFunc1();
      
          var self = this;
          var innerFunc2 = function () {
            console.log(self);
          };
          innerFunc2();
        },
      };
      obj1.outer();
      

문자열에 배열 메서드 사용은 왜 에러를 던질까?

문자열의 경우 length 프로퍼티가 읽기 전용이기 때문에 원본 문자열에 변경을 가하는 메서드(push, pop, shift, unshift, splice 등)는 에러를 던지며 .. (p.83)

유사배열객체에는 배열 메서드가 적용이 되는데 문자열에는 안되는 이유가 뭘까?

ch1에서 공부했다싶이, 기본형 데이터는 불변값이고 참조형 데이터는 가변값이기 때문이다.

참조형 데이터의 변수영역은 얼마든지 다른 값을 바라볼 수 있기 때문에, 가변값이라고 설명할 수 있다.

유사배열객체에 배열 메서드를 적용

  • 객체는 가변값이다. 따라서 다음과 같이 변경을 가하는 행위가 허용된다.
var obj = {
	0: 'a',
	1: 'b',
	2: 'c',
	length: 3
};

Array.prototype.push.call(obj, 'd') // {0: 'a', 1: 'b', 2: 'c', 3: 'd', length: 4}

문자열에 배열 메서드를 적용

  • 문자열은 기본형 데이터인 불변값이다.
  • 따라서 변경을 가하는 행위는 에러를 던진다.
var str = 'abc def';

Array.prototype.push.call(str, ', pushed string');
  • 에러: Uncaught TypeError: Cannot assign to read only property 'length' of object '[object String]'

0개의 댓글