Operador this

Hubo errores de script en esta página. Mientras los editores del sitio lo solucionan, puedes ver un contenido parcial debajo.

Resumen

La palabra clave this se refiere al objeto de contexto (comúnmente conocido como el objeto actual {{ mediawiki.external('current object') }}). En general, en un método, this se refiere a la invocación del objeto.

Operador
Implementado en: JavaScript 1.0
ECMA Versión: ECMA-262

Sintaxis

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

Descrictión

this es sólo de lectura

El objeto de contexto puede ser considerado como un parámetro oculto que es pasado a una función. Existen 4 maneras en las cuales this puede ser pasado:

Tipo Disparado por this
Método call objeto.método(arg1, arg2) objeto
Método Invocar Funciones función.call(objeto, arg1, arg2) objeto
Método aplicar Funciónes función.apply(objeto, {{ mediawiki.external('arg1, arg2') }}) objeto
Manejo de eventos/td> un evento el evento objetivo que es una propiedad del manejador de eventos

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.

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');
alert(foo.getBrand());

As expected, this outputs "toyota".

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

This unexpectedly outputs "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 outputted 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;
alert(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';
alert(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 doing so will create a closure keeping all the objects pointed to from local variables in the same scope, so you'll have to be careful to not introduce memory leaks.

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( { "en": "en/Core_JavaScript_1.5_Reference/Operators/Special_Operators/this_Operator", "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" } ) }}

Etiquetas y colaboradores del documento

Colaboradores de esta página: Sheppy, Mgjbot
Última actualización por: Mgjbot,