>  기사  >  웹 프론트엔드  >  자바스크립트에서 이것의 사용에 대한 자세한 설명

자바스크립트에서 이것의 사용에 대한 자세한 설명

巴扎黑
巴扎黑원래의
2017-08-21 10:31:191268검색


다른 많은 객체 지향 언어와 마찬가지로 JavaScript에도 this 키워드가 있는데, 이 키워드는 함수에서 이 메서드를 호출하는 객체를 가리키는 데 사용됩니다. 실제 프로그래밍에서 이것이 누구를 가리키는지 결정하려면 일반적으로 다음 원칙을 따를 수 있습니다.

  • 함수가 Function.call 또는 Function.apply에 의해 호출되는 경우 이는 call/apply의 첫 번째 매개변수를 가리킵니다. 매개변수가 null이거나 정의되지 않은 경우 이는 전역 객체를 가리킵니다(브라우저에서 전역 객체는 창 객체입니다).

  • Function.bind에 의해 함수가 호출되면 이는 바인드의 첫 번째 매개변수(메서드가 생성될 때)를 가리킵니다.

  • 함수가 개체에 의해 메서드로 호출되면 this는 이 개체를 가리킵니다.

  • 함수가 단지 함수로 호출되고 어떤 개체에도 연결되지 않은 경우 이는 전역 변수 창을 가리킵니다.

Function

먼저 "함수"를 살펴보겠습니다:

function introduce() {
   alert("Hello, I am Laruence
");
}

이 함수에서 this 키워드는 누구를 가리키는가?

글로벌하게 정의된 함수의 경우 함수의 소유자는 현재 페이지, 즉 윈도우 객체입니다.

그래서 함수를 따옴표로 묶었습니다. 왜냐하면 전역적으로 정의된 함수는 실제로는 윈도우 객체의 메소드이기 때문입니다.

그래서 함수 이름을 통해 직접 호출하거나, 윈도우 메소드 이름을 통해 호출할 수 있습니다. 이때 메소드의 this 키워드는 소유자인 윈도우 객체를 가리킵니다.

윈도우의 도입 속성을 확인하면 다음과 같은 결과가 나옵니다:

var name = "I am Laruence";
function introduce() {
   alert(this.name);
}
alert(window.introduce);
/**
* output:
* function introduce() {
* alert(this.name);
* }
*/

After 위의 코드를 읽으면 아마도 전역 함수는 창 개체의 메서드이고 전역 변수는 창 개체의 속성(이미 Javasript 범위에서 언급됨)이므로 다음을 통해 전역 변수에 액세스할 수 있다고 생각할 것입니다. 전역 함수에 this 키워드가 있죠?

답은 yes 입니다. Introvert 함수를 호출하면 저를 Laruence라고 알 수 있을 겁니다.

이벤트 처리 함수

아마도 이것에 대해 혼란을 주는 대부분의 이유는 함수에서 가져온 키워드(메서드)는 이벤트 처리 중에 사용됩니다.

<input id="name" type="text" name="name" value="Laruence" />

예를 들어, 이제 "이름" 입력 상자를 클릭하면 이름 입력 상자의 값을 표시해야 합니다. 그러면 다음 코드를 작성할 수 있습니다. :

function showValue() {
   alert(this.value);
}
document.getElementById("name").onclick = showValue;

위 코드는 Normal로 실행되는데 왜 함수의 this 포인터가 항상 함수 소유자를 가리킨다는 뜻이 아닌가요?

하하, 이 질문이 생각난다면 나를 진지하게 바라보고 있다는 뜻입니다. 기사, 그렇지 않으면 처음부터 읽어보는 것이 좋습니다. 그렇지 않으면 읽고 나서도 여전히 혼란스러울 것입니다~

그렇습니다. 위 코드에서는 showValue가 전역 객체에 정의되어 있으므로 onclick 이벤트 바인딩에서만 문제가 발생할 수 있는 것으로 보입니다. 이제 결정해야 할 때입니다.

JS의 모든 것은 객체이고, 함수와 메소드도 속성이라는 것을 알고 있습니다. 그러나 함수에는 실행 가능한 내부 속성이 있습니다. 따라서 위 코드의 경우 onclick을 바인딩하기 전에 실제로는 name이라는 id를 가진 입력 상자 Dom 개체의 onclick 속성에 값을 할당합니다. showValue 함수를 이름 입력 상자 객체의 onclick 속성에 복사합니다. 이때 onclick을 보면:

function showValue() {
   alert(this.value);
}
document.getElementById("name").onclick = showValue;
alert(document.getElementById("name").onclick);
/**
* output
* function showValue() {
* alert(this.value);
* }
*/

그래서 이벤트가 트리거되면 이름 입력 상자의 onclick 메서드가 호출됩니다. 시간이 지나면 this 키워드는 자연스럽게 이름 입력란을 가리키게 됩니다.

그런데 다음과 같은 쓰기 방식이

<span class="kwd">function</span><span class="pln"> showValue</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><br/><span class="pln">   alert</span><span class="pun">(</span><span class="kwd">this</span><span class="pun">.</span><span class="pln">value</span><span class="pun">);</span><br/><span class="pun">}</span><br/><span class="pun"><</span><span class="pln">input id</span><span class="pun">=</span><span class="str">"name"</span><span class="pln"> type</span><span class="pun">=</span><span class="str">"text"</span><span class="pln"> name</span><span class="pun">=</span><span class="str">"name"</span><span class="pln"> value</span><span class="pun">=</span><span class="str">"Laruence"</span><span class="pln"> onclick</span><span class="pun">=</span><span class="str">"showValue()"</span><span class="pun">/></span>

정상적으로 실행되지 않는데 왜 그럴까요?

글쎄요. 과제가 아니라 참조입니다.

onclick을 작성하는 두 가지 방법에 주의를 기울이면 다음을 발견할 수 있습니다. 이전 방법에서는 다음을 사용했습니다.

dom.onclick = showvalue; //没有调用符

이전 방법에서는

onclick = "showvalue()" //有调用符

이 둘 사이의 차이점도 반영할 수 있습니다. 전자의 경우 할당이고 후자의 경우 참조입니다. 이렇게 하면 입력 상자의 onclick 속성을 확인하면 다음과 같은 결과를 얻습니다.

<span class="pln">alert</span><span class="pun">(</span><span class="pln">dom</span><span class="pun">.</span><span class="pln">onclick</span><span class="pun">);</span><br/><span class="com">/**</span><br/><span class="com">* output:</span><br/><span class="com">* function onclick() {</span><br/><span class="com">*  showValue();</span><br/><span class="com">* }</span><br/><span class="com">*/</span>

보시죠? 차이점이 무엇인지 이해가 되시나요?

이 시점에서 IE에서 시도해 볼 수 있는 매우 흥미로운 예가 있습니다.

<img src="xxx" onerror="alert(1);} function hi() { alert(2); " />

이것의 포인팅을 변경하세요

이제 이유를 알았으니 어떻게 할 수 있습니까? 우리가 가리키고 싶은 곳을 가리킨다고요?

위의 이벤트 처리 함수에 대해 다음과 같은 방법으로 작성할 수 있습니다.

dom.onclick = showValue();
dom.onclick = function() { alert(this.value) ;}
<input onclick="alert(this.value);" /> //想想刚才我们的引用,是如何把这句嵌入的.
dom.addEventListener(dom, showValue, false); //ff only

이벤트 처리 함수가 아닌 상황의 경우 적용 또는 호출을 사용하여 이 키워드의 포인터를 변경하세요.

예:

var laruence = {
   name : "laruence",
   age : 26,
   position : "Senior PHP Engineer",
   company : "Baidu.inc"
};
 
function introduce() {
   alert(this.name);
}
 
introduce.call(laruence);

Function.call에 의해 함수가 호출됩니다.

var myObject = {
  sayHello : function() {
    console.log("Hi! My name is " + this.myName);
  },
  myName : "Rebecca"
};
var secondObject = {
  myName : "Colin"
};
myObject.sayHello();         // logs "Hi! My name is Rebecca"
myObject.sayHello.call(secondObject); // logs "Hi! My name is Colin"

함수가 호출됩니다. Function.call이 호출되는 예:

var myName = "the global object",
  sayHello = function () {
    console.log("Hi! My name is " + this.myName);
  },
  myObject = {
    myName : "Rebecca"
  };
var myObjectHello = sayHello.bind(myObject);
sayHello();    // logs "Hi! My name is the global object"
myObjectHello(); // logs "Hi! My name is Rebecca"

객체에 의해 호출되는 함수의 예:

var myName = "the global object",
  sayHello = function() {
    console.log("Hi! My name is " + this.myName);
  },
  myObject = {
    myName : "Rebecca"
  },
  secondObject = {
    myName : "Colin"
  };
myObject.sayHello = sayHello;
secondObject.sayHello = sayHello;
sayHello();        // logs "Hi! My name is the global object"
myObject.sayHello();   // logs "Hi! My name is Rebecca"
secondObject.sayHello(); // logs "Hi! My name is Colin"

깊은 네임스페이스에서 함수를 호출할 때 일반적으로 코드 양을 줄이기 위해 호출할 함수를 가리키는 변수를 캐시합니다. 하지만 그렇게 하면 함수에서 this의 값이 변경되고 궁극적으로 잘못된 작업이 수행됩니다. 예:

var myNamespace = {
  myObject : {
    sayHello : function() {
      console.log("Hi! My name is " + this.myName);
    },
    myName : "Rebecca"
  }
};
var hello = myNamespace.myObject.sayHello;
hello(); // logs "Hi! My name is undefined"

그래서 코드 양을 절약하기 위해 변수를 캐시하려는 경우 올바른 방법은 해당 함수를 호출하는 객체까지만 저장하는 것입니다.

var myNamespace = {
  myObject : {
    sayHello : function() {
      console.log("Hi! My name is " + this.myName);
    },
    myName : "Rebecca"
  }
};
var obj = myNamespace.myObject;
obj.sayHello(); // logs "Hi! My name is Rebecca"

간단히 말하면 큰 원칙이 있습니다. 해당 함수를 호출하면 누구를 가리킬 것입니다.

위 내용은 자바스크립트에서 이것의 사용에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.