this Operator

이 페이지에 스크립팅 에러가 있습니다. 사이트 편집기에 의해 보여지는 동안, 아래에 있는 콘텐트를 부분적으로 볼 수 있습니다.

요약

this 키워드는 현재(문맥) 객체를 참조합니다. 일반적으로 메소드에서 this는 객체를 부르는 데 이용합니다.

연산자
구현 내역: JavaScript 1.0
ECMA Version: ECMA-262

사용 방법

this{{ mediawiki.external('.propertyName') }}

설명

this은 읽기 전용입니다.

현재 문맥내 객체는 함수로 전달된 "숨은 파라미터"로 고려 합니다. this를 받는 네 가지 방법이 있습니다.

형식 적용 방식 this
method call object.method(arg1, arg2) object
Function's call method func.call(object, arg1, arg2) object
Function's apply method func.apply(object, {{ mediawiki.external('arg1, arg2') }}) object
event handling an event the event target that the event handler is a property of

The last case (event handling) is actually not intrinsic to JavaScript. Events are part of the DOM, not of JavaScript, i.e. the JavaScript engine has nothing to do with events. (JavaScript merely provides a binding to the DOM.)

If none of the above ways are used, the global object is passed as the context object (e.g. when this occurs at top-level outside of any functions, or when a function is called without being called on an object as in func(arg1, arg2);).

Method binding

As a consequence of this being "passed" to functions, this is not fixed for a function. That means that a function does not have an "owner" or "parent", even if it is a method. In other words, a method is not bound to the object that it is a method of.

To illustrate the concept of binding, consider the following:

function Car(brand) {
   this.brand = brand;
}
Car.prototype.getBrand = function() {
   return this.brand;
}
var foo = new Car("toyota");
print(foo.getBrand()); // assumes a print function is defined

As expected, this outputs "toyota".

var brand = "not a car";
var bar = foo.getBrand;
bar();

This unexpectedly returns "not a car" instead of "toyota". Since bar() is not a method call, the context object is not passed. this then defaults to the global object, which is window in a browser environment. The global object, in turn, also has a property called brand with the value "not a car". If it did not have a property called brand, undefined would have been returned instead.

This indicates that bar is not linked in any way to foo. Rather, the function referred to by bar and foo.getBrand is not bound to its "parent object", foo. An object may have a property referring to the function, but that function does not belong to that object. The distinction between methods and functions is made only when they are called: method calls pass the "parent object" as this, while function calls pass the global object as this.

Specifically, this in the function is not automatically supplied by foo. Instead this is supplied by the function call. That is, in the expression foo.getBrand(), foo is passed as this to the function referred to by foo.getBrand. All of the following are equivalent:

foo.getBrand()
bar.call(foo)
foo.getBrand.call(foo)

This lack of method binding is intended. It allows methods to be "shared" or "moved" from object to object. Continuing the previous example:

function Airplane(brand) {
   this.brand = brand;
}
var plane = new Airplane("boeing");

plane does not have a getBrand method, but it does have a brand property, making it compatible with Car's getBrand method. Therefore, the function referred to by Car.prototype.getBrand can be "shared" to either an object constructed by Airplane or Airplane.prototype (which would add the method to all objects constructed by Airplane):

Airplane.prototype.getBrand = Car.prototype.getBrand;
print(plane.getBrand());

The function is not actually copied. It is shared; Airplane.prototype.getBrand and Car.prototype.getBrand refer to the exact same function object. For example:

Airplane.prototype.getBrand.new_prop = "hello";
print(Car.prototype.getBrand.new_prop);

This outputs 'hello', indicating that Airplane.prototype.getBrand and Car.prototype.getBrand are one and the same.

A common way to trigger this problem is to pass an object's method as a callback. For example using setTimeout() or addEventListener():

setTimeout(obj.func, 1000); // sets wrong |this|!
document.addEventListener("load", obj.func, false); // sets wrong |this|!

A simple workaround is to pass an anonymous function as a callback:

document.addEventListener("load", function(event) { obj.func(event); }, false);

Note that this anonymous function has access to all variables in its enclosing environment, and the memory these variables use may not be reclaimed by the JavaScript engine as long as the anonymous function might be used (i.e. the event listener is registered). While only obj need actually be preserved for the function, an engine might choose to preserve other variables, too, increasing memory overhead. Calling removeEventListener or removing all references to an anonymous function will allow the variables' memory to be reclaimed, and you should be careful to do so to allow unused memory to be efficiently reclaimed by the JavaScript engine.

Another option in the case of addEventListener() is to pass an object with a handleEvent() method:

var obj = {
  // ...
  handleEvent: function(e) {
    // ...
  }
}
document.addEventListener("load", obj, false)

Examples

Example: Using this in an event handler

Suppose a function called validate validates an object's value property, given the object and the high and low values:

function validate(obj, lowval, hival) {
  if (obj.value < lowval || obj.value > hival)
    alert("Invalid Value!");
}

You could call validate in each form element's onChange event handler, using this to pass it the form element, as in the following example:

<b>Enter a number between 18 and 99:</b>
<input type="text" name="age" size="3"
   onchange="validate(this, 18, 99);"/>



{{ languages( { "es": "es/Referencia_de_JavaScript_1.5/Operadores/Operadores_especiales/Operador_this", "fr": "fr/R\u00e9f\u00e9rence_de_JavaScript_1.5_Core/Op\u00e9rateurs/Op\u00e9rateurs_sp\u00e9ciaux/L\'op\u00e9rateur_this", "ja": "ja/Core_JavaScript_1.5_Reference/Operators/Special_Operators/this_Operator", "pl": "pl/Dokumentacja_j\u0119zyka_JavaScript_1.5/Operatory/Operatory_specjalne/Operator_this", "en": "en/Core_JavaScript_1.5_Reference/Operators/Special_Operators/this_Operator" } ) }}

Document Tags and Contributors

Contributors to this page: Channy
Last updated by: Channy,