JavaScript 의 네가 모 르 는 this

7331 단어
중요 한 말
this 를 잘 알 아야 자바 스 크 립 트 로 구 글 지도 와 같은 대형 복잡 한 애플 리 케 이 션 을 만 들 수 있 습 니 다.
이 글 이 등장 한 배경
1. this 우리 개발 과정 에서 의 중요성 (개발 장면) - 코드 를 통 해 this 를 간단하게 이해
'더욱 우아 한 방식 으로 암시 적' 전달 '대상 의 인용 을 제공 하여 API 디자인 을 더욱 간결 하고 선명 하 게 한다.
먼저 코드 를 보 겠 습 니 다. 여 기 는 this 를 사용 하지 않 습 니 다. identify () 와 speak () 에 표 시 된 컨 텍스트 대상 을 입력 해 야 합 니 다.
//    you & me  
var me = {
    name: "Kyle"
};
var you = {
    name: "Reader"
};

function identify(context) {
    return context.name.toUpperCase();
}
function speak(context) {
    var greeting = "Hello, I'm " + identify( context );
    console.log( greeting );
}

identify( you ); // READER
speak( me ); //hello,    KYLE

this 해결 사용: 서로 다른 컨 텍스트 대상 (me 와 you) 에서 함수 identify () 와 speak () 를 중복 사용 할 수 있 습 니 다.
function identify() {
    return this.name.toUpperCase();
}
function speak() {
    var greeting = "Hello, I'm " + identify.call( this );
    console.log( greeting );
}

identify.call( me ); // KYLE
identify.call( you ); // READER

speak.call( me ); // Hello,    KYLE
speak.call( you ); // Hello,    READER

분명히, 당신 의 사용 모델 이 갈수 록 복잡 해 지면 서, 현식 전달 상하 문 대상 은 코드 를 더욱 혼 란 스 럽 게 할 것 이다. this 는 당신 의 코드 를 더욱 우아 하 게 할 수 있다.특히 대상 (관련) 과 원형 을 사용 할 때 this 를 이용 하여 함수 가 적당 한 문맥 대상 을 자동 으로 참조 할 수 있 도록 하 는 것 이 특히 중요 합 니 다.
2. 두 가지 잘못된 이해
  • this 지향 함수 자체
  • this 가 가리 키 는 함수 의 역할 영역 입 니 다. 이것 은 어떤 상황 에서 정확 하지만 다른 상황 에서 확실히 잘못된 것 입 니 다
  • 사실 일부 사람들 은 'this 는 함수 자체 도 가리 키 지 않 고 함수 의 품사 작용 역 도 가리 키 지 않 는 다' 고 생각 하지만 옳지 않다. 어떤 상황 에서 this 는 함수 자 체 를 가리 키 고 품사 작용 역 도 가리 킬 수 있다.
    3. 본질
    this 는 실행 (함수 호출) 할 때 바 인 딩 이 발생 합 니 다. 작성 할 때 바 인 딩 이 아 닙 니 다. 상하 문 은 함수 호출 시의 여러 가지 조건 에 달 려 있 습 니 다. 이것 이 가리 키 는 것 은 함수 가 어디에서 호출 되 느 냐 에 달 려 있 습 니 다.
    2. this 귀속 규칙 & 우선 순위
    쉽게 말 하면, 이것 은 대략 네 가지 가 있다.
  • new 에서 호출 (new 바 인 딩)
  • 함수 가 콜, apply (명시 적 바 인 딩) 또는 하 드 바 인 딩 을 통 해 호출 되 었 는 지 여부
  • 함수 가 특정한 문맥 대상 에서 호출 되 었 는 지 여부 (암시 적 바 인 딩)
  • 기본 귀속
  • 1. 기본 귀속
    다른 규칙 을 적용 할 수 없 을 때 기본 규칙 입 니 다. 엄격 한 모드 에서 undefined 에 연결 되 어 있 지 않 으 면 전역 대상 에 연결 되 어 있 습 니 다.
    가장 많이 사용 되 는 함수 호출 유형: 독립 함수 호출
    function foo() {
        console.log( this.a );
    }
    
    var a = 2;
    foo(); // 2
    

    코드 에서 foo () 는 아무런 수식 이 없 는 함수 참조 로 호출 되 며, this 의 기본 바 인 딩 에 만 적용 되 며, 다른 규칙 을 적용 할 수 없 기 때문에 this 는 전체 대상 을 가리 키 고 있 습 니 다.
    //      
    function foo() {
        "use strict";
        console.log( this.a );
    }
    
    var a = 2;
    foo(); // TypeError: this is undefined
    

    그래서 이런 문법 은 추천 하지 않 습 니 다.
    2. 스텔스 귀속
    호출 위치 에 상하 문 대상 이 있 는 지, 혹은 어떤 대상 에 포함 되 어 있 는 지 를 고려 하 다
    함수 가 컨 텍스트 대상 을 참조 할 때 암시 적 바 인 딩 규칙 은 함수 호출 중의 this 를 이 컨 텍스트 대상 에 연결 합 니 다.
    한 대상 내부 에 지향 함수 의 속성 을 포함 하고 이 속성 을 통 해 함 수 를 간접 적 으로 인용 하여 this 간접 (암시 적) 을 이 대상 에 연결 해 야 합 니 다.
    function foo() {
        console.log(this.a);
    }
    var obj = {
        a: 2,
        foo: foo
    };
    
    obj.foo(); // 2
    

    대상 속성 참조 체인 중 마지막 층 만 호출 위치 에 영향 을 줍 니 다. 즉, 스 택 의 끝 을 호출 합 니 다.
    function foo() {
        console.log( this.a );
    }
    var obj2 = {
        a: 42,
        foo: foo
    };
    var obj1 = {
        a: 2,
        obj2: obj2
    };
    
    obj1.obj2.foo(); // 42
    

    3. 귀속 표시
    일부 대상 을 강제로 지정 하여 함 수 를 호출 합 니 다. this 는 호출 함수 의 대상 을 강제 적 으로 가리 킵 니 다.
  • call(thisObj, arg1, arg2, arg3...)
  • apply(thisObj, argArr)
  • ES5 에 내 장 된 방법 을 제공 하여 bid (thisObj)
  • 를 하 드 바 인 딩 합 니 다.
    귀속 필드 보이 기
    function foo() {
        console.log( this.a );
    }
    var obj = {
        a:2
    };
    
    foo.call( obj ); // 2
    

    하 드 귀속 상용 필드
    function foo(something) {
        console.log( this.a, something );
        return this.a + something;
    }
    var obj = {
        a:2
    };
    
    var bar = foo.bind( obj );
    var b = bar( 3 ); // 2 3
    console.log( b ); // 5
    

    4. 새로운 귀속
    new 방식 의 우선 순위 가 가장 높 습 니 다. new 방식 으로 구조 함 수 를 호출 하면 this 는 new 호출 함수 가 새로 만 든 대상 을 가리 킬 것 입 니 다.
    function foo(a) {
        this.a = a;
    }
    var bar = new foo(2);
    
    console.log( bar.a ); // 2
    

    3. 귀속 예외
    1. 화살표 함수
    실제 원인 은 화살표 함수 가 자신의 this 가 전혀 없 기 때문이다.
    this 가 가리 키 는 고정 화 는 화살표 함수 내부 에 this 를 연결 하 는 메커니즘 이 있 기 때 문 이 아 닙 니 다. 실제 원인 은 화살표 함수 가 자신의 this 가 없 기 때 문 입 니 다. this 는 계승 되 어 온 것 입 니 다. 기본 값 은 이 를 정의 할 때 있 는 대상 (숙주 대상) 을 가리 키 고 있 습 니 다.그 소재 (즉 정 의 된 위치) 상하 문 에 있 는 this 값 을 포획 하여 자신의 this 값 으로 하고 현재 화살표 함수 작용 역 에서 변 수 를 찾 지 못 하면 이전 작용 역 에서 찾 은 것 처럼 내부 의 this 가 외층 코드 블록의 this 입 니 다
    // demo 1
    function foo() {
         setTimeout(() => {
            console.log('id:', this.id);
          }, 100);
    }
    var id = 21;
    foo.call({ id: 42 }) // id: 42
    
    //demo 2
    function Person() {
        this.name = 'dog';
        this.age = '18';
        setTimeout( () => {
            console.log(this);
            console.log('my name:' + this.name + '& my age:' + this.age)
        }, 1000)
    }
    var p = Person();
    
    

    2. 무시 되 는 this
    바 인 딩 된 것 이 null 이면 기본 바 인 딩 규칙 을 사용 합 니 다.
    //      null    undefined    this         call 、 apply    bind ,           ,
                
    function foo() {
        console.log( this.a );
    }
    var a = 2222;
    foo.call( null ); // 2222
    

    4. (암시 적) 귀속 분실
    가장 흔히 볼 수 있 는 this 바 인 딩 문 제 는 암시 적 으로 바 인 딩 된 함수 가 바 인 딩 대상 을 잃 어 버 리 는 것 입 니 다. 또한 기본 바 인 딩 을 사용 하여 this 를 전체 대상 이나 undefined 에 연결 하 는 것 은 엄격 한 모델 인지 여부 에 달 려 있 습 니 다.
    1. 인용 할당 분실
    function foo() {
        console.log( this.a );
    }
    var obj = {
        a: 2,
        foo: foo
    };
    var bar = obj.foo; //     !
    var a = "oops, global"; // a        
    
    bar(); // "oops, global"
    

    bar 는 obj. foo 의 인용 이지 만 실제 적 으로 foo 함수 자 체 를 인용 합 니 다. 이것 은 var bar = foo, obj 대상 은 중간 교량 일 뿐 obj. foo 는 전달 함수 역할 만 하기 때문에 bar 는 obj 대상 과 아무런 관계 가 없습니다. 이때 bar () 는 아무런 수식 이 없 는 함수 호출 입 니 다. bar 자 체 는 a 속성 이 없습니다.따라서 기본 바 인 딩 을 사 용 했 습 니 다. 마지막 으로 a 는 window 만 가리 킬 수 있 습 니 다.
    2. 인삼 분실
    function foo() {
        console.log( this.a );
    }
    function doFoo(fn) {
        // fn      foo
        fn(); // 

    매개 변수 전달 은 일종 의 암시 적 할당 이 므 로 함수 에 들 어 갈 때 도 암시 적 할당 을 받 기 때문에 결 과 는 이전 예 와 같 습 니 다.
    3. 리 턴 함수 분실
    function thisTo(){
       console.log(this.a);
    }
    var data={
        a:2,
        foo:thisTo //      this    
    };
    var a=3;//    
    
    setTimeout(data.foo,100);// 3
    

    전 삼 분실 이란 this 를 포함 하 는 함 수 를 매개 변수 로 함수 에 전달 할 때 this 지향 이 바 뀌 는 것 입 니 다.setTimeout 함수 의 원래 표기 법 은 setTimeout(function(){......},100); 100 ms 이후 에 실 행 된 함수 가 모두 ".................................................그래서 지금 이 순간 은 data. foo 를 매개 변수 로 하 는 것 입 니 다. setTimeout (thisto, 100) 입 니 다.100 ms 이후 에 thisto () 를 실행 하면 실제 이 치 는 1.1 과 차이 가 많 지 않 습 니 다. thisto 를 호출 하 는 대상 이 없습니다. this 는 window 만 가리 킬 수 있 습 니 다. 실제로 리 셋 함수 의 실행 방식 을 제어 할 수 없고 바 인 딩 된 호출 위치 에 영향 을 줄 수 있 습 니 다. 따라서 리 셋 함수 가 this 바 인 딩 을 잃 어 버 리 는 것 은 매우 흔 합 니 다. 심지어 더욱 예상 치 못 한 것 은...리 셋 함 수 를 호출 하 는 함 수 는 this 를 수정 할 수 있 습 니 다. 특히 일부 유행 하 는 JavaScript 라 이브 러 리 에서 시간 처리 기 는 리 셋 함수 의 this 를 트리거 이벤트 의 DOM 요소 에 강제로 연결 합 니 다.
    총결산
    네 가지 규칙:
  • new 에서 호출 (new 바 인 딩)
  • call, apply (명시 적 바 인 딩) 또는 하 드 바 인 딩 호출
  • 을 통 해
  • 함수 가 특정한 문맥 대상 에서 호출 되 었 는 지 여부 (암시 적 바 인 딩)
  • 기본 귀속
  • 특수 상황 특수 처리:
  • 화살표 함수
  • 무시 되 는 this
  • 귀속 분실
  • 좋은 웹페이지 즐겨찾기