실제로 이것은 진부한 문제입니다. 이것에 대한 기사가 많이 있습니다. 사실, 나는 그것을 알아 냈다고 생각했지만 어제는 프로젝트 중에도 여전히 의심의 여지가있었습니다. 나는 JavaScript Weekly (나중에 링크가 있었고 희토류에 대한 중국어 번역이 첨부되었습니다)와 선배가 권장하는 또 다른 기사에서 수집하고 읽은 자세한 기사에 대해 생각 했으므로, 나는 그들을보고 이것에 대한 나의 이해는 실제로 조금 향상되었습니다.
JavaScript의 'This'는 동적이며 함수가 선언 될 때가 아니라 함수가 실행될 때 결정됩니다. 모든 함수는 'this'를 호출 할 수 있으며, 함수가 객체에 속하든 상관 없습니다. 이와 관련하여 주로 네 가지 상황이 있습니다.
1. 객체로 사용 된 방법이 호출됩니다
함수가 객체로 간주되는 메소드 인 경우,이 함수 의이는 객체를 가리 킵니다.
var John = {FirstName : "John"} function func () {alert (this.firstname + ": hi!")} john.sayhi = func john.sayhi () // this = john여기에 주목할만한 가치가 있습니다. 객체의 메소드가 꺼내어 변수에 할당되면, 메소드는 함수 트리거가되며 이는 창 또는 언더 파인드 (엄격한 모드)를 가리 킵니다.
2. 함수 내에서 호출하십시오
이 기능에 이것을 갖는 경우 실제로는 메소드라고 불립니다. 둘 사이를 호출하는 것은 창 객체로 취급하는 것과 같습니다. 이것은 창을 가리 킵니다. ES5는 실제로 이것 = 정의되지 않은 것으로 규정하고 있으며, 기존 방법에 따라 여전히 브라우저 만 실행됩니다 (최신 버전의 Chrome, Safari 및 Firefox All Point to Window (201607)에서 테스트).
func () function func () {alert (this) // [Object Window] 또는 [Object Global] 또는 종류의 ..}이것을 통과시키기 위해서는 ()는 이전에 obj.a 또는 obj [ 'a']와 유사한 참조 유형이어야하며 다른 것이 될 수 없습니다.
여기에 작은 구덩이도 있습니다. 객체의 메소드에 함수가 있으면 기능이 실제로 함수 모드로 트리거되므로 기본값은 창으로 (엄격한 모드에서 정의되지 않음). 해결책은 이것을 함수에 바인딩하는 것입니다.
var numbers = {numbera : 5, numberb : 10, sum : function () {console.log (this === 숫자); // => true 함수 계산 () {// 이것은 strict mode console.log (this === 숫자)에서 창에서 정의되지 않았거나 정의되지 않았습니다. // => false return this.numbera + this.numberb; } return calculate (); }}; 숫자 .sum (); // => NAN 또는 Strows TypeError는 엄격한 모드 var var var var var var = {numbera : 5, numberb : 10, sum : function () {console.log (this === 숫자); // => true function accement () {console.log (this === 숫자); // => true return this.numbera + this.numberb; } // .call () 메소드를 사용하여 컨텍스트 return return.call (this)을 수정합니다. }}; 숫자 .sum (); // => 153. 신규로 전화하십시오
객체를 참조하는 변수는 실제로 객체에 대한 참조를 저장합니다. 즉, 변수는 실제로 실제 데이터에 대한 포인터를 저장합니다.
새 키워드를 사용하는 경우이 변경 사항은 실제로 다음 단계를 수행합니다.
이것을 생성 = {}.
이것은 새로운 실행 중에 변경 될 수 있으며 속성과 방법이 추가됩니다.
이 변경 사항을 반환합니다.
기능 동물 (이름) {this.name = name this.canwalk = true} var 동물 = 새로운 동물 ( "Beastie") 경고 (Animal.name)생성자가 객체를 반환하면 반환 된 객체를 가리 킵니다.
기능 동물 () {this.name = 'Mousie'; this.age = '18'; return {name : 'Godzilla'} // <- 반환}} var 동물 = new Animal () Console.log (Animal.name) // Godzilla Console.log (Animal.age) // undefined새로 사용하는 것을 잊지 않는다는 점에 유의해야합니다. 그렇지 않으면 새로운 기능이 생성되지 않습니다. 대신 함수 호출과 동등한 함수를 실행하면 실제로 창을 가리 킵니다.
함수 차량 (유형, wheelscount) {this.type = type; this.wheelscount = wheelscount; 이것을 반환합니다;} // 함수 invocationvar car = Vehicle ( 'car', 4); car.type; // => 'car'car.wheelscount // => 4 car === Window // => true4. 이것을 명확하게 전화하고, 전화를 사용하고 적용하십시오
이것은 가장 자바 스크립트에서 영감을 얻은 곳입니다.
다음 코드 :
func.call(obj, arg1, arg2,...)
첫 번째 매개 변수는이의 참조 객체로 사용되며 후속 매개 변수는 함수의 매개 변수로 사용됩니다. 해결책은 바인드를 사용하는 것입니다.
기능 동물 (유형, 다리) {this.type = 유형; this.legs = 다리; this.loginfo = function () {console.log (this === mycat); // => true console.log ( ' + this.type +'는 ' + this.legs +'다리 '가 있습니다); };} var mycat = 새로운 동물 ( 'cat', 4); // "고양이는 4 개의 다리가 있습니다"settimeout을 기록합니다 (mycat.loginfo.bind (mycat), 1000); // settimeout ?? var John = {FirstName : "John", Design : "Smith"} function func (a, b) {alert (this [a] + '' + this [b])} func.call (John, 'FirstName', 'Surname') // "John Smith"적용에 관해서는 배열 제곱의 매개 변수를 전달하고 다른 부분은 다음과 같습니다.
func.call (John, 'FirstName', 'Surname') func.Apply (John, [ 'firstName', 'Surname'])
또한 ES5의 클래스 상속에 사용하여 부모 생성자를 호출 할 수 있습니다.
함수 러너 (이름) {console.log (이 인스턴스 토끼); // => true this.name = 이름; } 함수 토끼 (이름, countlegs) {console.log (이 인스턴스 토끼); // => true // 간접적으로 호출, 부모 생성자 러너 .call (this, name); countlegs = countlegs; } var myrabbit = 새로운 토끼 ( '흰 토끼', 4); Myrabbit; // {이름 : 'White Rabbit', countlegs : 4}5..bind ()
.apply () 및 .call ()을 비교하는데, 둘 다 기능을 즉시 실행하는 반면 .bind () 함수는이 사전 지정을 바인딩하고 통화를 지연시킬 수있는 새 메소드를 반환합니다.
.bind () 메소드의 함수는 새 함수를 만드는 것입니다. 실행 중 컨텍스트는 .bind ()가 전달되는 첫 번째 매개 변수로,이 사전 설정이있는 함수를 생성 할 수 있습니다.
var numbers = {배열 : [3, 5, 10], getNumbers : function () {return this.array; }}; // 바운드 기능 생성 VONDGETNUMBERS = NUMBES.GETNUMBERS.BIND (숫자); boundgetNumbers (); // => [3, 5, 10] // ObjectVar에서 메소드를 추출합니다. SimpleGetNumbers (); // => 정의되지 않았거나 엄격한 모드에서 오류를 던집니다..bind ()를 사용할 때 .bind ()는 영원한 맥락 체인을 생성하고 수정할 수 없습니다. 바인딩 함수가 .call () 또는 .apply ()를 사용하여 다른 다른 컨텍스트로 전달 되더라도 이전 연결의 컨텍스트를 변경하지 않으며 리빈딩은 어떤 역할도하지 않습니다.
생성자를 호출 할 때만 바인딩 함수는 컨텍스트를 변경할 수 있지만 이는 특히 권장되는 접근법이 아닙니다.
6. 화살표 기능
화살표 함수는 자체 실행 컨텍스트를 생성하지 않으므로 정의시 정의 된 외부 함수에 따라 다릅니다.
컨텍스트 변경 방법을 사용하더라도 컨텍스트를 한 번 바인딩 한 후 화살표 기능을 변경할 수 없습니다.
var 번호 = [1, 2]; (function () {var get = () => {console.log (this === numbers); // => true this;}; console.log (this === 숫자); // => true get (); // => [1, 2] // 화살표 기능 사용 .apply () 및 .call (); [0]); // 2]; // => [1, 2] // bind get.bind ([0]) ();화살표 함수는 정적 컨텍스트를 가지며 다른 통화로 인해 변경되지 않기 때문입니다. 따라서 화살표 기능을 사용하여 방법을 정의하지 마십시오
함수 기간 (시간, 분) {this.hours = 시간; this.minutes = 분; } periz.prototype.format = () => {console.log (this === Window); // => true this.hours + '시간 및' + this.minutes + 'mings'; }; var walkperiod = 새로운 기간 (2, 30); walkperiod.format (); // => '정의되지 않은 시간 및 정의되지 않은 분'참조하십시오
"this"의 4 가지 향기
JavaScript의 'This'키워드에 대한 부드러운 설명
자바 스크립트이 미스터리 (번역)
그것을 이해하지 못하는 학생들이 권장됩니다. 위의 세 기사를 확인하십시오. 세 번째 기사는 두 번째 기사의 번역입니다. 이것에 대해 궁금한 점이 있다면, 함께 토론하고, 의사 소통하고, 사고를 홍보하며 함께 진전을 이룰 수 있습니다.