더 이상 방황 하지 않 기: 자바 스 크 립 트 의 this 를 완전히 이해 합 니 다.

7975 단어 this자바 script
사실 this 는 늘 말 하 는 문제 이다.this 에 관 한 글 이 매우 많 습 니 다. 사실 저 는 이 글 을 알 고 있 었 다 고 생각 했 습 니 다. 그런데 어제 프로젝트 를 하 는 과정 에서 궁금 증 이 생 겼 습 니 다. 아마 전에 JavaScript weekly 에서 보 려 고 했 던 this 에 대한 상세 한 글 (뒤에 링크 가 있 고 희토 류 에 있 는 중국어 번역문 도 첨부 되 었 습 니 다) 과 다른 선배 가 추천 한 글 을 생각 하고 이 를 보 았 습 니 다.this 에 대한 인식 이 확실히 향상 되 었 다.
JavaScript 의 'this' 는 동적 입 니 다. 함수 가 실 행 될 때 함수 성명 이 아 닌 함수 가 실 행 될 때 확 정 됩 니 다.모든 함수 가 'this' 를 호출 할 수 있 습 니 다. 이것 은 이 함수 가 특정한 대상 에 속 하 는 지 에 관 한 것 이 없습니다.this 에 관 해 서 는 주로 다음 과 같은 네 가지 상황 이 있다.
1. 대상 이 되 는 방법 이 호출 됨
만약 이 함수 가 어떤 대상 으로 간주 되 는 방법 이 라면, 이 함수 의 this 는 이 대상 을 가리킨다.
    var john = {
      firstName: "John"
    }
    function func() {
      alert(this.firstName + ": hi!")
    }
    john.sayHi = func
    john.sayHi()  // this = john

한 대상 의 방법 이 변 수 를 할당 할 때 이 방법 은 함수 로 변 경 됩 니 다. this 는 window 나 underfind (엄격 한 모드) 를 가리 키 고 있 습 니 다.
2. 함수 내 호출
함수 에 this 가 있 으 면 방법 으로 호출 되 었 음 을 의미 합 니 다. 그 사이 에 그 를 window 대상 으로 하 는 방법 을 호출 합 니 다. this 는 window 를 가리 키 고 있 습 니 다. 주의해 야 할 것 은 ES5 는 이러한 상황 this=undefined 을 규정 하고 있 습 니 다. 브 라 우 저 만 대부분 오래된 방법 으로 실 행 됩 니 다 (본인 이 최신 버 전의 Chrome, Safari, Firefox 에서 테스트 는 window (201607) 를 가리 키 고 있 습 니 다.불 여우 아래 에서 엄격 한 모드 로 undefined 를 가리 키 기;
    func()
    function func() {
        alert(this) // [object Window] or [object global] or kind of..
    }

전달 this 을 위해 () 이전 에는 인용 유형 이 어야 하 며 obj.a 또는 obj['a'] 과 유사 해 야 하 며 다른 것 이 아 닙 니 다.
여기에 작은 구덩이 가 존재 합 니 다. 대상 의 방법 에 함수 가 존재 할 때 이 함 수 는 함수 모드 로 트리거 되 기 때문에 this 기본 값 은 window (엄격 한 모드 에서 undefined) 해결 방법 은 이 함수 에 this 를 연결 하 는 것 입 니 다.
var numbers = {  
   numberA: 5,
   numberB: 10,
   sum: function() {
     console.log(this === numbers); // => true
     function calculate() {
       // this is window or undefined in strict mode
       console.log(this === numbers); // => false
       return this.numberA + this.numberB;
     }
     return calculate();
   }
};
numbers.sum(); // => NaN or throws TypeError in strict mode  
var numbers = {  
   numberA: 5,
   numberB: 10,
   sum: function() {
     console.log(this === numbers); // => true
     function calculate() {
       console.log(this === numbers); // => true
       return this.numberA + this.numberB;
     }
     // use .call() method to modify the context
     return calculate.call(this);
   }
};
numbers.sum(); // => 15  

3. new 에서 호출
인용 대상 의 변 수 는 실제 적 으로 이 대상 에 대한 인용 을 저장 합 니 다. 즉, 변 수 는 실제 데이터 에 대한 지침 을 저장 합 니 다.new 키 워드 를 사용 할 때 this 의 변 화 는 다음 과 같은 몇 가지 가 있 습 니 다.
  • 창설 this = {}.
  • new 가 실행 하 는 과정 에서 변 경 될 수 있 습 니 다 this. 그리고 속성 과 방법 을 추가 합 니 다.
  • 변 경 된 것 으로 되 돌아 갑 니 다 this.
  •     function Animal(name) {
            this.name = name
            this.canWalk = true
        }
        var animal = new Animal("beastie")
        alert(animal.name)

    주의해 야 할 것 은 구조 함수 가 대상 을 되 돌려 주면 this 는 되 돌아 오 는 대상 을 가리킨다.
        function Animal() {
            this.name = 'Mousie';
            this.age = '18';
            return {
                name: 'Godzilla'
            } // 

    여기 서 주의해 야 할 것 은 new 를 사용 하 는 것 을 잊 지 마 세 요. 그렇지 않 으 면 새로운 함 수 를 만 들 지 않 습 니 다.함수 만 실 행 했 을 뿐 함수 호출 에 해당 합 니 다. this 는 사실 window 를 가리 키 고 있 습 니 다.
    function Vehicle(type, wheelsCount) {  
      this.type = type;
      this.wheelsCount = wheelsCount;
      return this;
    }
    // Function invocation
    var car = Vehicle('Car', 4);  
    car.type;       // => 'Car'  
    car.wheelsCount // => 4  
    car === window  // => true 

    4. 명확 한 호출 this, 사용 callapply이것 은 가장 자 바스 크 립 트 특색 이 있 는 곳 이다.다음 코드:
      func.call(obj, arg1, arg2,...)

    첫 번 째 매개 변 수 는 this 의 대체 대상 이 되 고 그 후의 매개 변 수 는 함수 의 매개 변수 로 되 며 해결 방법 은 bid 를 사용 하 는 것 입 니 다.
    function Animal(type, legs) {  
      this.type = type;
      this.legs = legs;  
      this.logInfo = function() {
        console.log(this === myCat); // => true
        console.log('The ' + this.type + ' has ' + this.legs + ' legs');
      };
    }
    var myCat = new Animal('Cat', 4);  
    // logs "The Cat has 4 legs"
    setTimeout(myCat.logInfo.bind(myCat), 1000); 
    // setTimeout??
      var john = {
        firstName: "John",
        surname: "Smith"
      }
      function func(a, b) {
        alert( this[a] + ' ' + this[b] )
      }
      func.call(john, 'firstName', 'surname')  // "John Smith"
    

    apply 에 대해 서 는 배열 의 측 으로 매개 변 수 를 전달 할 뿐 다른 부분 은 똑 같 습 니 다. 다음 과 같 습 니 다.
      func.call(john, 'firstName', 'surname')
      func.apply(john, ['firstName', 'surname'])

    그것들 도 ES5 의 클래스 계승 에서 부모 구조 기 를 호출 하 는 데 사용 할 수 있다.
        function Runner(name) {  
          console.log(this instanceof Rabbit); // => true
          this.name = name;  
        }
        function Rabbit(name, countLegs) {  
          console.log(this instanceof Rabbit); // => true
          //     ,        
          Runner.call(this, name);
          this.countLegs = countLegs;
        }
        var myRabbit = new Rabbit('White Rabbit', 4);  
        myRabbit; // { name: 'White Rabbit', countLegs: 4 }

    5. .bind()
    비교 방법. apply () 와. call () 은 둘 다 함 수 를 즉시 실 행 했 고. bid () 함 수 는 새로운 방법 을 되 돌려 주 었 습 니 다. 미리 지정 한 this 를 연결 하고 호출 을 연기 할 수 있 습 니 다.bid () 방법의 역할 은 새로운 함 수 를 만 드 는 것 입 니 다. 실 행 될 때 문맥 환경 은. bid () 가 전달 하 는 첫 번 째 매개 변수 입 니 다. this 함 수 를 미리 설정 할 수 있 습 니 다.
    var numbers = {  
      array: [3, 5, 10],
      getNumbers: function() {
        return this.array;    
      }
    };
    // Create a bound function
    var boundGetNumbers = numbers.getNumbers.bind(numbers);  
    boundGetNumbers(); // => [3, 5, 10]  
    // Extract method from object
    var simpleGetNumbers = numbers.getNumbers;  
    simpleGetNumbers(); // => undefined or throws an error in strict mode  
    .bind() 를 사용 할 때 주의해 야 합 니 다. bid () 는 영원한 컨 텍스트 체인 을 만 들 었 습 니 다. 수정 할 수 없습니다.하나의 바 인 딩 함수 가. call () 이나. apply () 를 사용 하여 다른 컨 텍스트 환경 에 들 어 와 도 이전에 연 결 된 컨 텍스트 환경 을 변경 하지 않 고 다시 연결 해도 아무런 역할 을 하지 않 습 니 다.구조 기 가 호출 될 때 만 바 인 딩 함수 가 문맥 을 바 꿀 수 있 지만 특별히 추천 하 는 방법 은 아 닙 니 다.
    6. 화살표 함수
    화살표 함 수 는 자신 이 실행 하 는 컨 텍스트 를 만 들 지 않 습 니 다. this 는 정의 할 때 외부 함수 에 달 려 있 습 니 다.화살표 함수 가 상하 문 을 한 번 에 연결 하면 변경 할 수 없습니다. 상하 문 변경 방법 을 사용 하 더 라 도:
        var numbers = [1, 2];  
        (function() {  
          var get = () => {
            console.log(this === numbers); // => true
            return this;
          };
          console.log(this === numbers); // => true
          get(); // => [1, 2]
          //        .apply()   .call()
          get.call([0]);  // => [1, 2]
          get.apply([0]); // => [1, 2]
          // Bind
          get.bind([0])(); // => [1, 2]
        }).call(numbers);

    이것 은 화살표 함수 가 정적 인 상하 문 환경 을 가지 고 있 기 때문에 서로 다른 호출 로 인해 변 하지 않 기 때문이다.따라서 화살표 함수 정의 방법 을 사용 하지 마 십시오.
    function Period (hours, minutes) {  
          this.hours = hours;
          this.minutes = minutes;
        }
        Period.prototype.format = () => {  
          console.log(this === window); // => true
          return this.hours + ' hours and ' + this.minutes + ' minutes';
        };
        var walkPeriod = new Period(2, 30);  
        walkPeriod.format(); // => 'undefined hours and undefined minutes' 

    레 퍼 런 스
  • Four scents of "this"
  • Gentle explanation of 'this' keyword in JavaScript
  • JavaScript This 의 수수께끼 (번역문)
  • 이해 하지 못 했다 고 생각 하 는 학생 들 에 게 위의 세 편의 문장 을 보 세 요. 그 중에서 세 번 째 편 은 두 번 째 번역문 입 니 다.만약 여러분 이 this 에 대해 의문 이 있다 면, 여러분 이 함께 토론 하고, 교류 하고, 사 고 를 촉진 하 며, 공동으로 진보 하 는 것 을 환영 합 니 다.

    좋은 웹페이지 즐겨찾기