js에서this의 지향 문제를 철저히 이해하다

4407 단어 javascriptthis
평소에 js,react 등 코드를 쓸 때this를 사용하는 경우가 많습니다. 자신만만하게 코드를 쓰고 실행을 눌렀을 때 오류this.xxx is undefinedthis.xxx is not a function를 발견했지만 자신의 코드에 분명히 정의xxx가 있습니다.왜 이런 오류가 발생했을까, 사실this이 가리키는 대상에 정의가 없는 것xxx이다.그래서 this의 지향을 이해하는 것은 매우 필요하다.

1. 컨텍스트 실행


this를 말하기 전에 상하문 집행을 실행하는 상하문은 세 가지 부분이 있다.
  • 변수 객체(Variable Object, VO)
  • 작용역 체인
  • this

  • 여기 안에 있는this가 바로 본문에서 말하고자 하는 것이다this실행 컨텍스트는 다음과 같습니다.
  • 글로벌 실행 컨텍스트
  • 함수 실행 상하문
  • 전역 실행 상하문은 코드가 실행될 때 만들어지고 함수 실행 상하문은 함수가 호출될 때 만들어진다. 같은 함수는 서로 다른 시간에 호출되면 서로 다른 실행 상하문을 만든다.

    2.this의 지향


    this는 실행 상하문에 존재하고 실행 상하문은 코드가 실행되고 함수가 호출될 때 만들어지기 때문에this의 지향도 코드가 실행되고 함수가 호출될 때 확정된다.
    this가 사용할 수 있는 서로 다른 장면은 this의 지향을 세 가지 상황으로 나눈다.
  • 전역의this
  • 함수 중의this
  • 구조 함수 중의this
  • 전역의this


    브라우저에서 전역적인this는 window,node를 가리킨다.js에서 전역적인this지향globel.
    var a = 1;
    console.log(this);  // window
    console.log(this.a);  // 1
    console.log(window.a);  // 1
    console.log(this === window);  // true

    함수 중의this


    함수 호출 방식에 따라 다음과 같은 두 가지 상황으로 나눌 수 있다.
  • 함수가 대상의 방법으로 호출되었을 때의this
  • 함수가 독립적으로 호출되었을 때의this
  • 1. 대상 방법 중의this 함수가 대상 중의 방법으로 호출될 때 함수에서this는 함수의 소유자를 가리킨다.
    var a = 111;
    var obj = {
        a: 222,
        func: function() {
            console.log(this);  // obj
            console.log(this.a);  // 222
        }
    }
    obj.func();

    여기func 에서 obj 안의 방법으로 호출되었기 때문에 func 안의 this가 가리키는 것은 func 의 소유자이고, 여기서obj2. 독립적으로 호출될 때 함수가 독립적으로 호출될 때 함수 안의this는 전역 상하문 안의this, 즉window를 가리킨다. 에서this사undefined.
    var a = 111;
    function func1(){
        var a = 222;
        console.log(this);  // window
        console.log(this.a);  // 111
    }
    func1();
    
    function func2(){
        "use strict"
        console.log(this);  // undefined
    }
    func2();

    ES6 화살표 함수의 this


    화살표 함수에서this지향은 함수 정의를 할 때 정해진 것으로 성명식 함수 정의와 다르다.화살표 함수를 정의할 때 함수this는 상하문에 있는this를 가리킨다
    var func = () => {
        console.log(this);  // window
    }
    func();

    func 함수는 화살표 함수이기 때문에func 함수 안의this는 그 정의가 확정적이다. 정의할 때 존재하는 집행 상하문은 전역적으로 집행하는 상하문이고 상하문 중의this는 window를 가리키기 때문에func 함수의this가 가리키는 것은this이다.
    var a = 111;
    var obj = {
        a: 222,
        func: function() {
            var fun2 = () => {
                var a = 333;
                console.log(this.a);
            }
            fun2();
        }
    }
    obj.func();

    이 코드에서func 함수를 호출할 때func 안의this는obj를 가리키고func 함수에 화살표 함수를 정의했기 때문에func2 함수 안의this는func 함수가 상하문 안의this를 실행하는 것을 가리키기 때문에 마지막으로 출력된 것은obj 안의a(222)이다.

    ** 구조 함수 중의this


    함수 new를 작성하여 객체를 만드는 프로세스:
  • 새 대상 만들기;
  • 구조 함수의this를 이 새로운 대상을 가리킨다.
  • 구조 함수 내부 코드 집행;
  • 이 새 대상을 되돌려줍니다
  • 구조 함수 중의this는 생성된 대상을 가리킨다
    function Obj(a){
        this.a = a;
        this.func = function(){
            console.log(this);
            console.log(this.a);
        }
    }
    var obj = new Obj(2);
    obj.func();

    이 코드에서 new 실례화 대상을 사용한 후 호출 대상 안의 func 함수, 이곳의 func 함수는 obj 안의 한 방법이기 때문에 func 함수 안의 this는 함수 소유자를 가리키기 때문에 인쇄한 결과2입니다.

    3. this가 가리키는 방법을 바꾸다


    콜, apply,bind를 사용하여 함수 안의this의 지향을 바꿀 수 있습니다
    var a = 111;
    var obj1 = {
        a: 222,
        func: function() {
            console.log(this); // {a: 333}
            console.log(this.a); // 333
        }
    }
            
    var obj2 = {
        a: 333,
    }
    obj1.func.call(obj2,);

    여기에 obj1에 있는func 방법을 호출할 때 뒤에 콜을 추가하면 func에 있는this가 콜에 지정된obj2를 가리키기 때문에 마지막으로 인쇄한 것은 333입니다. 여기서 콜을 호출하면 함수가 바로 실행됩니다.
    ply 방법과call의 작용은 같다. 그들 사이의 차이점은 call이 다른 매개 변수를 전달할 때 하나의 전달이고 apply는 하나의 수조를 전달한다. 이렇게 하면 전달된 데이터의 개수가 증가할 때call처럼 콜 뒤의 괄호 안에 쓰지 않아도 된다는 것이다.예를 들면 다음과 같습니다.
    obj.func.call(obj2,param1,pram2,param3)
    obj.func.aplly(obj2,[param1,pram2,param3])

    bind도 함수 안의this 지향을 바꿀 수 있다. 콜과 apply의 차이점은 새로운 함수를 되돌려주고 콜과 apply처럼 바로 실행하지 않는다는 것이다.
    참고 자료
    MDN-this

    좋은 웹페이지 즐겨찾기