w3schools method entendiendo javascript this

javascript - method - ¿Cómo funciona la palabra clave "this"?



let in javascript w3schools (20)

Me he dado cuenta de que no parece haber una explicación clara de qué es this palabra clave y cómo se utiliza correctamente (e incorrectamente) en JavaScript en el sitio de desbordamiento de pila.

He sido testigo de algún comportamiento muy extraño con él y no he entendido por qué ha ocurrido.

¿Cómo funciona this y cuándo debe usarse?


Javascript es this

Invocación de función simple

Considera la siguiente función:

function foo() { console.log("bar"); console.log(this); } foo(); // calling the function

Tenga en cuenta que estamos ejecutando esto en el modo normal, es decir, el modo estricto no se utiliza.

Cuando se ejecuta en un navegador, el valor de this se registra como window . Esto se debe a que la window es la variable global en el alcance de un navegador web.

Si ejecuta este mismo fragmento de código en un entorno como node.js, this se referirá a la variable global en su aplicación.

Ahora si ejecutamos esto en modo estricto agregando la instrucción "use strict"; al comienzo de la declaración de función, this ya no se referiría a la variable global en ninguno de los entornos. Esto se hace para evitar confusiones en el modo estricto. this , en este caso, simplemente se registra undefined , porque eso es lo que es, no está definido.

En los siguientes casos, veríamos cómo manipular el valor de this .

Llamando una función sobre un objeto

Hay maneras diferentes de hacer esto. Si ha llamado a métodos nativos en Javascript como forEach y slice , ya debería saber que this variable en ese caso se refiere al Object en el que llamó a esa función (Tenga en cuenta que en javascript, casi todo es un Object , incluyendo Array s y Function s). Tome el siguiente código, por ejemplo.

var myObj = {key: "Obj"}; myObj.logThis = function () { // I am a method console.log(this); } myObj.logThis(); // myObj is logged

Si un Object contiene una propiedad que contiene una Function , la propiedad se llama un método. Este método, cuando se invoca, siempre tendrá this variable establecida en el Object que está asociado. Esto es cierto para los modos estrictos y no estrictos.

Tenga en cuenta que si un método se almacena (o, más bien, se copia) en otra variable, la referencia a this ya no se conserva en la nueva variable. Por ejemplo:

// continuing with the previous code snippet var myVar = myObj.thisMethod; myVar(); // logs either of window/global/undefined based on mode of operation

Teniendo en cuenta un escenario más comúnmente práctico:

var el = document.getElementById(''idOfEl''); el.addEventListener(''click'', function() { console.log(this) }); // the function called by addEventListener contains this as the reference to the element // so clicking on our element would log that element itself

La new palabra clave

Considere una función constructora en Javascript:

function Person (name) { this.name = name; this.sayHello = function () { console.log ("Hello", this); } } var awal = new Person("Awal"); awal.sayHello(); // In `awal.sayHello`, `this` contains the reference to the variable `awal`

¿Como funciona esto? Bueno, veamos qué sucede cuando usamos la new palabra clave.

  1. Si se llama a la función con la new palabra clave, se inicializa inmediatamente un Object de tipo Person .
  2. El constructor de este Object tiene su constructor establecido en Person . Además, tenga en cuenta que typeof awal solo devolvería Object .
  3. A este nuevo Object se le asignaría el prototipo de Person.prototype . Esto significa que cualquier método o propiedad en el prototipo de Person estaría disponible para todas las instancias de Person , incluyendo awal .
  4. La función Person sí se invoca ahora; siendo this una referencia al objeto recién construido awal .

Bastante franco, ¿eh?

Tenga en cuenta que la especificación oficial de ECMAScript donde se indica que dichos tipos de funciones son funciones reales del constructor . Solo son funciones normales, y las new pueden usarse en cualquier función. Es solo que los usamos como tales, y por eso los llamamos solo como tales.

Llamando funciones en Funciones: call y apply

Así que sí, dado que las function s también son Objects (y, de hecho, variables de primera clase en Javascript), incluso las funciones tienen métodos que son ... bueno, funciones seleccionadas.

Todas las funciones heredan de la Function global, y dos de sus muchos métodos son de call y apply , y ambos pueden usarse para manipular el valor de this en la función en la que se llaman.

function foo () { console.log (this, arguments); } var thisArg = {myObj: "is cool"}; foo.call(thisArg, 1, 2, 3);

Este es un ejemplo típico de uso de call . Básicamente toma el primer parámetro y lo establece en la función foo como una referencia a thisArg . Todos los demás parámetros pasados ​​a la call se pasan a la función foo como argumentos.
Así que el código anterior registrará {myObj: "is cool"}, [1, 2, 3] en la consola. Muy buena manera de cambiar el valor de this en cualquier función.

apply es casi lo mismo que aceptar call ya que solo toma dos parámetros: thisArg y una matriz que contiene los argumentos que se pasarán a la función. Por lo tanto, la call anterior se puede traducir para apply esta manera:

foo.apply(thisArg, [1,2,3])

Tenga en cuenta que la call y la apply pueden anular el valor de this invocación del método de establecer por punto que analizamos en la segunda viñeta. Suficientemente simple :)

Presentando .... se bind !

bind es un hermano de call y se apply . También es un método heredado por todas las funciones del constructor de Function global en Javascript. La diferencia entre bind y call / apply es que tanto la call como la apply invocarán la función. bind , por otro lado, devuelve una nueva función con el thisArg y los arguments . Tomemos un ejemplo para entender mejor esto:

function foo (a, b) { console.log (this, arguments); } var thisArg = {myObj: "even more cool now"}; var bound = foo.bind(thisArg, 1, 2); console.log (typeof bound); // logs `function` console.log (bound); /* logs `function () { native code }` */ bound(); // calling the function returned by `.bind` // logs `{myObj: "even more cool now"}, [1, 2]`

¿Ves la diferencia entre los tres? Es sutil, pero se utilizan de manera diferente. Al igual que call y apply , bind también anulará el valor de this conjunto mediante la invocación del método de puntos.

También tenga en cuenta que ninguna de estas tres funciones modifica la función original. call y apply devolverían el valor de las funciones recién creadas, mientras que bind devolverá la función recién creada, lista para ser llamada.

Cosas extra, copia esto

A veces, no le gusta el hecho de que this cambie con el alcance, especialmente el ámbito anidado. Echa un vistazo al siguiente ejemplo.

var myObj = { hello: function () { return "world" }, myMethod: function () { // copy this, variable names are case-sensitive var that = this; // callbacks ftw /o/ foo.bar("args", function () { // I want to call `hello` here this.hello(); // error // but `this` references to `foo` damn! // oh wait we have a backup /o/ that.hello(); // "world" }); } };

En el código anterior, vemos que el valor de this cambió con el alcance anidado, pero queríamos el valor de this del alcance original. Así que ''copiamos'' this a that y usamos la copia en lugar de this . Listo, ¿eh?

Índice:

  1. ¿Qué se mantiene en this por defecto?
  2. ¿Qué pasa si llamamos a la función como un método con notación de punto de objeto?
  3. ¿Qué pasa si usamos la new palabra clave?
  4. ¿Cómo manipulamos this con call y apply ?
  5. Utilizando bind .
  6. Copiando this para resolver problemas de alcance anidado.

Resumen de thisJavascript:

  • El valor de thisse determina por cómo no se invoca la función, ¡dónde se creó!
  • Por lo general, el valor de thisestá determinado por el Objeto que queda a la izquierda del punto. ( windowen el espacio global)
  • En los detectores de eventos, el valor de se thisrefiere al elemento DOM en el que se llamó al evento.
  • Cuando se llama a la función con la newpalabra clave, el valor de se thisrefiere al objeto recién creado
  • Se puede manipular el valor de thislas funciones: call, apply,bind

Ejemplo:

let object = { prop1: function () {console.log(this);} } object.prop1(); // object is left of the dot, thus this is object const myFunction = object.prop1 // We store the function in the variable myFunction myFunction(); // Here we are in the global space // myFunction is a property on the global object // Therefore it logs the window object

Ejemplos de oyentes de eventos:

document.querySelector(''.foo'').addEventListener(''click'', function () { console.log(this); // This refers to the DOM element the eventListener was invoked from }) document.querySelector(''.foo'').addEventListener(''click'', () => { console.log(this); // Tip, es6 arrow function don''t have their own binding to the this v }) // Therefore this will log the global object

.foo:hover { color: red; cursor: pointer; }

<div class="foo">click me</div>

Constructor de ejemplo:

function Person (name) { this.name = name; } const me = new Person(''Willem''); // When using the new keyword the this in the constructor function will refer to the newly created object console.log(me.name); // Therefore, the name property was placed on the object created with new keyword.


"esto" tiene que ver con el alcance. Cada función tiene su propio alcance, y como todo en JS es un objeto, incluso una función puede almacenar algunos valores en sí misma usando "esto". OOP 101 enseña que "esto" solo es aplicable a instancias de un objeto. Por lo tanto, cada vez que se ejecuta una función, una nueva "instancia" de esa función tiene un nuevo significado de "esto".

La mayoría de las personas se confunden cuando intentan usar "esto" dentro de funciones de cierre anónimo como:

(function(value) { this.value = value; $(''.some-elements'').each(function(elt){ elt.innerHTML = this.value; // uh oh!! possibly undefined }); })(2);

Así que aquí, dentro de cada (), "esto" no contiene el "valor" que usted espera (de

this.value = value; sobre eso). Por lo tanto, para superar este problema (no es un juego de palabras), un desarrollador podría:

(function(value) { var self = this; // small change self.value = value; $(''.some-elements'').each(function(elt){ elt.innerHTML = self.value; // phew!! == 2 }); })(2);

Pruébalo; Comenzarás a gustarte este patrón de programación.


Recomiendo leer primero el artículo Scope en JavaScript ( mirror ) de Mike West . Es una excelente y amigable introducción a los conceptos de this y las cadenas de alcance en JavaScript.

Una vez que empiezas a acostumbrarte a this , las reglas son bastante simples. El estándar ECMAScript 5.1 define this :

§11.1.1 La palabra clave this

La palabra clave this evalúa con el valor de ThisBinding del contexto de ejecución actual

ThisBinding es algo que el intérprete de JavaScript mantiene cuando evalúa el código de JavaScript, como un registro de CPU especial que contiene una referencia a un objeto. El intérprete actualiza ThisBinding al establecer un contexto de ejecución en uno de solo tres casos diferentes:

1. Contexto de ejecución global inicial.

Este es el caso del código JavaScript que se evalúa en el nivel superior, por ejemplo, cuando está directamente dentro de un <script> :

<script> alert("I''m evaluated in the initial global execution context!"); setTimeout(function () { alert("I''m NOT evaluated in the initial global execution context."); }, 1); </script>

Al evaluar el código en el contexto de ejecución global inicial, ThisBinding se establece en el objeto global, window ( §10.4.1.1 ).

Ingresando el codigo eval

  • ... mediante una llamada directa a eval() ThisBinding no se modifica; es el mismo valor que ThisBinding del contexto de ejecución de llamada ( §10.4.2 (2) (a)).

  • ... si no es por una llamada directa a eval()
    ThisBinding se establece en el objeto global como si se ejecutara en el contexto de ejecución global inicial ( §10.4.2 (1)).

§15.1.2.1.1 define lo que es una llamada directa a eval() . Básicamente, eval(...) es una llamada directa, mientras que algo como (0, eval)(...) o var indirectEval = eval; indirectEval(...); var indirectEval = eval; indirectEval(...); Es una llamada indirecta a eval() . Ver la respuesta de chuckj a (1, eval) (''this'') vs eval (''this'') en JavaScript? y el ECMA-262-5 de Dmitry Soshnikov en detalle. Capítulo 2. Modo estricto. para cuando podrías usar una llamada eval() indirecta.

Introducir código de función

Esto ocurre cuando se llama a una función. Si se llama a una función en un objeto, como en obj.myMethod() o el equivalente obj["myMethod"]() , ThisBinding se establece en el objeto ( obj en el ejemplo; §13.2.1 ). En la mayoría de los otros casos, ThisBinding se establece en el objeto global ( §10.4.3 ).

La razón para escribir "en la mayoría de los otros casos" es porque hay ocho funciones incorporadas de ECMAScript 5 que permiten que ThisBinding se especifique en la lista de argumentos. Estas funciones especiales toman un llamado thisArg que se convierte en ThisBinding al llamar a la función ( §10.4.3 ).

Estas funciones especiales incorporadas son:

  • Function.prototype.apply( thisArg, argArray )
  • Function.prototype.call( thisArg [ , arg1 [ , arg2, ... ] ] )
  • Function.prototype.bind( thisArg [ , arg1 [ , arg2, ... ] ] )
  • Array.prototype.every( callbackfn [ , thisArg ] )
  • Array.prototype.some( callbackfn [ , thisArg ] )
  • Array.prototype.forEach( callbackfn [ , thisArg ] )
  • Array.prototype.map( callbackfn [ , thisArg ] )
  • Array.prototype.filter( callbackfn [ , thisArg ] )

En el caso de las funciones Function.prototype , se llaman en un objeto de función, pero en lugar de establecer ThisBinding en el objeto de función, ThisBinding se establece en thisArg .

En el caso de las funciones Array.prototype , se llama al callbackfn dado en un contexto de ejecución donde ThisBinding se establece en thisArg si se proporciona; De lo contrario, al objeto global.

Esas son las reglas de JavaScript simple. Cuando comienzas a usar bibliotecas de JavaScript (por ejemplo, jQuery), puedes encontrar que ciertas funciones de la biblioteca manipulan el valor de this . Los desarrolladores de esas bibliotecas de JavaScript hacen esto porque tiende a admitir los casos de uso más comunes, y los usuarios de la biblioteca generalmente consideran que este comportamiento es más conveniente. Al pasar las funciones de devolución de llamada que hacen referencia a las funciones de la biblioteca, debe consultar la documentación para obtener garantías sobre el valor de this cuando se llama a la función.

Si se está preguntando cómo una biblioteca de JavaScript manipula el valor de this , la biblioteca simplemente está utilizando una de las funciones de JavaScript integradas que aceptan un thisArg . Usted también puede escribir su propia función tomando una función de devolución de llamada y thisArg :

function doWork(callbackfn, thisArg) { //... if (callbackfn != null) callbackfn.call(thisArg); }

Hay un caso especial que aún no mencioné. Al construir un nuevo objeto a través del new operador, el intérprete de JavaScript crea un nuevo objeto vacío, establece algunas propiedades internas y luego llama a la función de constructor en el nuevo objeto. Por lo tanto, cuando se llama a una función en un contexto de constructor, el valor de this es el nuevo objeto que creó el intérprete:

function MyType() { this.someData = "a string"; } var instance = new MyType(); // Kind of like the following, but there are more steps involved: // var instance = {}; // MyType.call(instance);

Sólo por diversión, prueba tu comprensión con algunos ejemplos.

Para revelar las respuestas, pase el mouse sobre los cuadros de color amarillo claro.

  1. ¿Cuál es el valor de this en la línea marcada? ¿Por qué?

    window - La línea marcada se evalúa en el contexto de ejecución global inicial.

    if (true) { // What is `this` here? }

  2. ¿Cuál es el valor de this en la línea marcada cuando se obj.staticFunction() ? ¿Por qué?

    obj : al llamar a una función en un objeto, ThisBinding se establece en el objeto.

    var obj = { someData: "a string" }; function myFun() { return this // What is `this` here? } obj.staticFunction = myFun; console.log("this is window:", obj.staticFunction() == window); console.log("this is obj:", obj.staticFunction() == obj);

  3. ¿Cuál es el valor de this en la línea marcada? ¿Por qué?

    window

    En este ejemplo, el intérprete de JavaScript ingresa el código de función, pero dado que no se llama a myFun / obj.myMethod en un objeto, ThisBinding se establece en la window .

    Esto es diferente de Python, en el que el acceso a un método ( obj.myMethod ) crea un objeto de método enlazado .

    var obj = { myMethod: function () { return this; // What is `this` here? } }; var myFun = obj.myMethod; console.log("this is window:", myFun() == window); console.log("this is obj:", myFun() == obj);

  4. ¿Cuál es el valor de this en la línea marcada? ¿Por qué?

    window

    Este fue complicado. Al evaluar el código de evaluación, this es obj . Sin embargo, en el código eval, myFun no se llama en un objeto, por lo que ThisBinding se establece en la window para la llamada.

    function myFun() { return this; // What is `this` here? } var obj = { myMethod: function () { eval("myFun()"); } };

  5. ¿Cuál es el valor de this en la línea marcada? ¿Por qué?

    obj

    La línea myFun.call(obj); está invocando la función incorporada especial Function.prototype.call() , que acepta a thisArg como el primer argumento.

    function myFun() { return this; // What is `this` here? } var obj = { someData: "a string" }; console.log("this is window:", myFun.call(obj) == window); console.log("this is obj:", myFun.call(obj) == obj);


Here hay una buena fuente de thisin JavaScript.

Aquí está el resumen:

  • global esto

    En un navegador, en el ámbito global, se thisencuentra el windowobjeto.

    <script type="text/javascript"> console.log(this === window); // true var foo = "bar"; console.log(this.foo); // "bar" console.log(window.foo); // "bar"

    En el nodeuso de la respuesta, thises el espacio de nombres superior. Puedes referirte a él como global.

    >this { ArrayBuffer: [Function: ArrayBuffer], Int8Array: { [Function: Int8Array] BYTES_PER_ELEMENT: 1 }, Uint8Array: { [Function: Uint8Array] BYTES_PER_ELEMENT: 1 }, ... >global === this true

    Al nodeejecutarse desde un script, thisen el ámbito global comienza como un objeto vacío. No es lo mismo queglobal

    //test.js console.log(this); // {} console.log(this === global); // fasle

  • funciona este

Excepto en el caso de los controladores de eventos DOM o cuando thisArgse proporciona una (ver más abajo), tanto en el nodo como en un navegador que utiliza thisuna función que no se llama con newreferencias al alcance global ...

<script type="text/javascript"> foo = "bar"; function testThis() { this.foo = "foo"; } console.log(this.foo); //logs "bar" testThis(); console.log(this.foo); //logs "foo" </script>

Si lo usas use strict;, en cuyo caso thisseráundefined

<script type="text/javascript"> foo = "bar"; function testThis() { "use strict"; this.foo = "foo"; } console.log(this.foo); //logs "bar" testThis(); //Uncaught TypeError: Cannot set property ''foo'' of undefined </script>

Si llama a una función con newel thisque será un nuevo contexto, no hará referencia al global this.

<script type="text/javascript"> foo = "bar"; function testThis() { this.foo = "foo"; } console.log(this.foo); //logs "bar" new testThis(); console.log(this.foo); //logs "bar" console.log(new testThis().foo); //logs "foo" </script>

  • prototipo este

Las funciones que creas se convierten en objetos de función. Obtienen automáticamente una prototypepropiedad especial , que es algo a lo que puede asignar valores. Cuando creas una instancia llamando a tu función new, obtendrás acceso a los valores que asignaste a la prototypepropiedad. Se accede a esos valores utilizando this.

function Thing() { console.log(this.foo); } Thing.prototype.foo = "bar"; var thing = new Thing(); //logs "bar" console.log(thing.foo); //logs "bar"

Por lo general, es un error asignar matrices u objetos en el archivoprototype . Si desea que las instancias tengan cada uno sus propios arreglos, créelos en la función, no en el prototipo.

function Thing() { this.things = []; } var thing1 = new Thing(); var thing2 = new Thing(); thing1.things.push("foo"); console.log(thing1.things); //logs ["foo"] console.log(thing2.things); //logs []

  • objetar esto

Puede usar thisen cualquier función en un objeto para referirse a otras propiedades en ese objeto. Esto no es lo mismo que una instancia creada con new.

var obj = { foo: "bar", logFoo: function () { console.log(this.foo); } }; obj.logFoo(); //logs "bar"

  • Evento DOM este

En un controlador de eventos HTML DOM, thissiempre es una referencia al elemento DOM al que se adjuntó el evento

function Listener() { document.getElementById("foo").addEventListener("click", this.handleClick); } Listener.prototype.handleClick = function (event) { console.log(this); //logs "<div id="foo"></div>" } var listener = new Listener(); document.getElementById("foo").click();

A menos que tú bindel contexto.

function Listener() { document.getElementById("foo").addEventListener("click", this.handleClick.bind(this)); } Listener.prototype.handleClick = function (event) { console.log(this); //logs Listener {handleClick: function} } var listener = new Listener(); document.getElementById("foo").click();

  • HTML esto

Dentro de los atributos HTML en los que puede poner JavaScript, thises una referencia al elemento.

<div id="foo" onclick="console.log(this);"></div> <script type="text/javascript"> document.getElementById("foo").click(); //logs <div id="foo"... </script>

  • eval esta

Se puede utilizar evalpara acceder this.

function Thing () { } Thing.prototype.foo = "bar"; Thing.prototype.logFoo = function () { eval("console.log(this.foo)"); //logs "bar" } var thing = new Thing(); thing.logFoo();

  • con este

Puede usarlo withpara agregar thisal alcance actual para leer y escribir valores thissin consultar thisexplícitamente.

function Thing () { } Thing.prototype.foo = "bar"; Thing.prototype.logFoo = function () { with (this) { console.log(foo); foo = "foo"; } } var thing = new Thing(); thing.logFoo(); // logs "bar" console.log(thing.foo); // logs "foo"

  • jQuery esto

jQuery en muchos lugares se thisreferirá a un elemento DOM.

<div class="foo bar1"></div> <div class="foo bar2"></div> <script type="text/javascript"> $(".foo").each(function () { console.log(this); //logs <div class="foo... }); $(".foo").on("click", function () { console.log(this); //logs <div class="foo... }); $(".foo").each(function () { this.click(); }); </script>


this en Javascript siempre se refiere al ''propietario'' de la función que se está ejecutando .

Si no se define un propietario explícito, se hace referencia al propietario más superior, el objeto de ventana.

Asi que si lo hice

function someKindOfFunction() { this.style = ''foo''; }

element.onclick = someKindOfFunction;

thisSe referiría al objeto objeto. Pero ten cuidado, mucha gente comete este error.

<element onclick="someKindOfFunction()">

En este último caso, simplemente hace referencia a la función, no se la entrega al elemento. Por lo tanto, thisse referirá al objeto de la ventana.


this palabra clave se comporta de manera diferente en JavaScript en comparación con otro idioma. En lenguajes orientados a objetos, this palabra clave se refiere a la instancia actual de la clase. En JavaScript, el valor de this está determinado principalmente por el contexto de invocación de la función ( context.function() ) y dónde se llama.

1. Cuando se utiliza en contexto global

Cuando usa this en un contexto global, está vinculado a un objeto global ( window en el navegador)

document.write(this); //[object Window]

Cuando usa this dentro de una función definida en el contexto global, this todavía está vinculado al objeto global ya que la función se convierte en un método de contexto global.

function f1() { return this; } document.write(f1()); //[object Window]

Por encima de f1 se hace un método de objeto global. Por lo tanto, también podemos llamarlo en el objeto window siguiente manera:

function f() { return this; } document.write(window.f()); //[object Window]

2. Cuando se usa dentro del método de objeto

Cuando utiliza this palabra clave dentro de un método de objeto, this está vinculado al objeto de encierro "inmediato".

var obj = { name: "obj", f: function () { return this + ":" + this.name; } }; document.write(obj.f()); //[object Object]:obj

Arriba he puesto la palabra inmediata entre comillas dobles. Es para señalar que si anida el objeto dentro de otro objeto, entonces this está vinculado al padre inmediato.

var obj = { name: "obj1", nestedobj: { name:"nestedobj", f: function () { return this + ":" + this.name; } } } document.write(obj.nestedobj.f()); //[object Object]:nestedobj

Incluso si agrega la función explícitamente al objeto como un método, aún sigue las reglas anteriores, es decir, this todavía apunta al objeto primario inmediato.

var obj1 = { name: "obj1", } function returnName() { return this + ":" + this.name; } obj1.f = returnName; //add method to object document.write(obj1.f()); //[object Object]:obj1

3. Al invocar la función sin contexto.

Cuando utiliza this función interna que se invoca sin ningún contexto (es decir, no en ningún objeto), está vinculada al objeto global ( window en el navegador) (incluso si la función está definida dentro del objeto).

var context = "global"; var obj = { context: "object", method: function () { function f() { var context = "function"; return this + ":" +this.context; }; return f(); //invoked without context } }; document.write(obj.method()); //[object Window]:global

Probando todo con funciones.

Podemos probar los puntos anteriores con funciones también. Sin embargo, hay algunas diferencias.

  • Anteriormente agregamos miembros a objetos usando la notación literal de objetos. Podemos agregar miembros a las funciones usando this . para especificarlos.
  • La notación literal de objetos crea una instancia de objeto que podemos usar inmediatamente. Con la función podemos necesitar crear primero su instancia utilizando un new operador.
  • También en un enfoque de objeto literal, podemos agregar miembros explícitamente a objetos ya definidos usando el operador de puntos. Esto se agrega a la instancia específica solamente. Sin embargo, he agregado una variable al prototipo de la función para que se refleje en todas las instancias de la función.

A continuación, probé todas las cosas que hicimos con Object y this arriba, pero primero creando una función en lugar de escribir directamente un objeto.

/********************************************************************* 1. When you add variable to the function using this keyword, it gets added to the function prototype, thus allowing all function instances to have their own copy of the variables added. *********************************************************************/ function functionDef() { this.name = "ObjDefinition"; this.getName = function(){ return this+":"+this.name; } } obj1 = new functionDef(); document.write(obj1.getName() + "<br />"); //[object Object]:ObjDefinition /********************************************************************* 2. Members explicitly added to the function protorype also behave as above: all function instances have their own copy of the variable added. *********************************************************************/ functionDef.prototype.version = 1; functionDef.prototype.getVersion = function(){ return "v"+this.version; //see how this.version refers to the //version variable added through //prototype } document.write(obj1.getVersion() + "<br />"); //v1 /********************************************************************* 3. Illustrating that the function variables added by both above ways have their own copies across function instances *********************************************************************/ functionDef.prototype.incrementVersion = function(){ this.version = this.version + 1; } var obj2 = new functionDef(); document.write(obj2.getVersion() + "<br />"); //v1 obj2.incrementVersion(); //incrementing version in obj2 //does not affect obj1 version document.write(obj2.getVersion() + "<br />"); //v2 document.write(obj1.getVersion() + "<br />"); //v1 /********************************************************************* 4. `this` keyword refers to the immediate parent object. If you nest the object through function prototype, then `this` inside object refers to the nested object not the function instance *********************************************************************/ functionDef.prototype.nestedObj = { name: ''nestedObj'', getName1 : function(){ return this+":"+this.name; } }; document.write(obj2.nestedObj.getName1() + "<br />"); //[object Object]:nestedObj /********************************************************************* 5. If the method is on an object''s prototype chain, `this` refers to the object the method was called on, as if the method was on the object. *********************************************************************/ var ProtoObj = { fun: function () { return this.a } }; var obj3 = Object.create(ProtoObj); //creating an object setting ProtoObj //as its prototype obj3.a = 999; //adding instance member to obj3 document.write(obj3.fun()+"<br />");//999 //calling obj3.fun() makes //ProtoObj.fun() to access obj3.a as //if fun() is defined on obj3

4. Cuando se utiliza dentro de la función de constructor .

Cuando la función se utiliza como un constructor (es decir, cuando se llama con una new palabra clave), this cuerpo interno de la función apunta al nuevo objeto que se está construyendo.

var myname = "global context"; function SimpleFun() { this.myname = "simple function"; } var obj1 = new SimpleFun(); //adds myname to obj1 //1. `new` causes `this` inside the SimpleFun() to point to the // object being constructed thus adding any member // created inside SimipleFun() using this.membername to the // object being constructed //2. And by default `new` makes function to return newly // constructed object if no explicit return value is specified document.write(obj1.myname); //simple function

5. Cuando se utiliza dentro de la función definida en la cadena prototipo

Si el método está en la cadena de prototipo de un objeto, this método interno se refiere al objeto en el que se invocó el método, como si el método estuviera definido en el objeto.

var ProtoObj = { fun: function () { return this.a; } }; //Object.create() creates object with ProtoObj as its //prototype and assigns it to obj3, thus making fun() //to be the method on its prototype chain var obj3 = Object.create(ProtoObj); obj3.a = 999; document.write(obj3.fun()); //999 //Notice that fun() is defined on obj3''s prototype but //`this.a` inside fun() retrieves obj3.a

6. Funciones internas de llamada (), aplicación () y vinculación ()

  • Todos estos métodos se definen en Function.prototype .
  • Estos métodos permiten escribir una función una vez e invocarla en un contexto diferente. En otras palabras, permiten especificar el valor de this que se utilizará mientras se ejecuta la función. También toman cualquier parámetro para pasar a la función original cuando se invoca.
  • fun.apply(obj1 [, argsArray]) Establece obj1 como el valor de this fun() interna fun() y llama a fun() pasar elementos de argsArray como sus argumentos.
  • fun.call(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]]) - Establece obj1 como el valor de this dentro de fun() y llama fun() pasando arg1, arg2, arg3, ... como sus argumentos.
  • fun.bind(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]]) - Devuelve la referencia a la función fun con this diversión interna vinculada a obj1 y los parámetros de obj1 a los parámetros especificados arg1, arg2, arg3,...
  • Por ahora, la diferencia entre apply , call y bind debe haberse hecho evidente. apply permite especificar los argumentos para funcionar como un objeto similar a una matriz, es decir, un objeto con una propiedad de length numérica y sus correspondientes propiedades enteras no negativas. Mientras que la call permite especificar los argumentos a la función directamente. Tanto la apply como la call invocan inmediatamente la función en el contexto especificado y con los argumentos especificados. Por otro lado, el bind simplemente devuelve la función vinculada al valor especificado, this y los argumentos. Podemos capturar la referencia a esta función devuelta asignándola a una variable y luego podemos llamarla en cualquier momento.

function add(inc1, inc2) { return this.a + inc1 + inc2; } var o = { a : 4 }; document.write(add.call(o, 5, 6)+"<br />"); //15 //above add.call(o,5,6) sets `this` inside //add() to `o` and calls add() resulting: // this.a + inc1 + inc2 = // `o.a` i.e. 4 + 5 + 6 = 15 document.write(add.apply(o, [5, 6]) + "<br />"); //15 // `o.a` i.e. 4 + 5 + 6 = 15 var g = add.bind(o, 5, 6); //g: `o.a` i.e. 4 + 5 + 6 document.write(g()+"<br />"); //15 var h = add.bind(o, 5); //h: `o.a` i.e. 4 + 5 + ? document.write(h(6) + "<br />"); //15 // 4 + 5 + 6 = 15 document.write(h() + "<br />"); //NaN //no parameter is passed to h() //thus inc2 inside add() is `undefined` //4 + 5 + undefined = NaN</code>

7. this dentro de los controladores de eventos

  • Cuando asigna la función directamente a los controladores de eventos de un elemento, el uso de this directamente dentro de la función de manejo de eventos se refiere al elemento correspondiente. Dicha asignación de función directa se puede realizar utilizando el método addeventListener o mediante los métodos tradicionales de registro de eventos como onclick .
  • De manera similar, cuando usa this directamente dentro de la propiedad del evento (como <button onclick="...this..." > ) del elemento, se refiere al elemento.
  • Sin embargo, el uso de this indirectamente a través de la otra función llamada dentro de la función de manejo de eventos o propiedad de evento se resuelve en la window objeto global.
  • El mismo comportamiento anterior se logra cuando adjuntamos la función al controlador de eventos usando el método de evento de registro de eventos de Microsoft. En lugar de asignar la función al controlador de eventos (y, por lo tanto, hacer el método de función del elemento), llama a la función en el evento (llamándola efectivamente en el contexto global).

Recomiendo probar mejor esto en JSFiddle .

<script> function clickedMe() { alert(this + " : " + this.tagName + " : " + this.id); } document.getElementById("button1").addEventListener("click", clickedMe, false); document.getElementById("button2").onclick = clickedMe; document.getElementById("button5").attachEvent(''onclick'', clickedMe); </script> <h3>Using `this` "directly" inside event handler or event property</h3> <button id="button1">click() "assigned" using addEventListner() </button><br /> <button id="button2">click() "assigned" using click() </button><br /> <button id="button3" onclick="alert(this+ '' : '' + this.tagName + '' : '' + this.id);">used `this` directly in click event property</button> <h3>Using `this` "indirectly" inside event handler or event property</h3> <button onclick="alert((function(){return this + '' : '' + this.tagName + '' : '' + this.id;})());">`this` used indirectly, inside function <br /> defined & called inside event property</button><br /> <button id="button4" onclick="clickedMe()">`this` used indirectly, inside function <br /> called inside event property</button> <br /> IE only: <button id="button5">click() "attached" using attachEvent() </button>


thises uno de los conceptos mal entendidos en JavaScript porque se comporta de manera diferente de un lugar a otro. Simplemente, se thisrefiere al "propietario" de la función que estamos ejecutando actualmente .

thisayuda a obtener el objeto actual (también conocido como contexto de ejecución) con el que trabajamos. Si entiende en qué objeto se está ejecutando la función actual, puede entender fácilmente qué corriente thises

var val = "window.val" var obj = { val: "obj.val", innerMethod: function () { var val = "obj.val.inner", func = function () { var self = this; return self.val; }; return func; }, outerMethod: function(){ return this.val; } }; //This actually gets executed inside window object console.log(obj.innerMethod()()); //returns window.val //Breakdown in to 2 lines explains this in detail var _inn = obj.innerMethod(); console.log(_inn()); //returns window.val console.log(obj.outerMethod()); //returns obj.val

Arriba creamos 3 variables con el mismo nombre ''val''. Uno en el contexto global, uno dentro de obj y el otro dentro de Método interno de obj. JavaScript resuelve los identificadores dentro de un contexto particular subiendo la cadena de alcance de local go global.

Pocos lugares donde thisdiferenciarse.

Llamando a un método de un objeto

var status = 1; var helper = { status : 2, getStatus: function () { return this.status; } }; var theStatus1 = helper.getStatus(); //line1 console.log(theStatus1); //2 var theStatus2 = helper.getStatus; console.log(theStatus2()); //1

Cuando se ejecuta la línea 1, JavaScript establece un contexto de ejecución (EC) para la llamada a la función, estableciendo thisel objeto al que hace referencia lo que vino antes del último "." .así que en la última línea puedes entender que a()se ejecutó en el contexto global que es el window.

Con constructor

this Se puede utilizar para referirse al objeto que se está creando.

function Person(name){ this.personName = name; this.sayHello = function(){ return "Hello " + this.personName; } } var person1 = new Person(''Scott''); console.log(person1.sayHello()); //Hello Scott var person2 = new Person(''Hugh''); var sayHelloP2 = person2.sayHello; console.log(sayHelloP2()); //Hello undefined

Cuando Person()se ejecuta nuevo, se crea un objeto completamente nuevo. Personse llama y thisse establece para hacer referencia a ese nuevo objeto.

Llamada de función

function testFunc() { this.name = "Name"; this.myCustomAttribute = "Custom Attribute"; return this; } var whatIsThis = testFunc(); console.log(whatIsThis); //window var whatIsThis2 = new testFunc(); console.log(whatIsThis2); //testFunc() / object console.log(window.myCustomAttribute); //Custom Attribute

Si perdemos la newpalabra clave, se whatIsThisrefiere al contexto más global que puede encontrar ( window)

Con manejadores de eventos

Si el controlador de eventos está en línea, se thisrefiere al objeto global

<script type="application/javascript"> function click_handler() { alert(this); // alerts the window object } </script> <button id=''thebutton'' onclick=''click_handler()''>Click me!</button>

Cuando se agrega un controlador de eventos a través de JavaScript, se thisrefiere al elemento DOM que generó el evento.

  • También puedes manipular el contexto usando .apply() .call()y.bind()
  • El proxy JQuery es otra forma que puede usar para asegurarse de que esto en una función sea el valor que desea. (Verifique que comprenda $ .proxy () , jQuery.proxy () uso )
  • Qué var that = thissignifica en JavaScript

Dado que este hilo se ha incrementado, he recopilado algunos puntos para lectores nuevos en el thistema.

¿Cómo se thisdetermina el valor de ?

Utilizamos esta similar a la forma en que usamos los pronombres en las lenguas naturales como el Inglés: “Juan está ejecutando rápido porque él está tratando de coger el tren.” En cambio, nos podríamos haber escrito “... John está tratando de coger el tren”.

var person = { firstName: "Penelope", lastName: "Barrymore", fullName: function () { // We use "this" just as in the sentence above: console.log(this.firstName + " " + this.lastName); // We could have also written: console.log(person.firstName + " " + person.lastName); } }

this no se le asigna un valor hasta que un objeto invoca la función donde está definido. En el ámbito global, todas las variables y funciones globales se definen en el windowobjeto. Por lo tanto, thisen una función global se refiere a (y tiene el valor de) el windowobjeto global .

Cuando use strict, thisen funciones globales y anónimas que no están vinculadas a ningún objeto, tiene un valor de undefined.

La thispalabra clave se entiende mejor cuando: 1) tomamos prestado un método que usa this, 2) asignamos un método que usa thisuna variable, 3) una función que usa thisse pasa como una función de devolución de llamada, y 4) thisse usa dentro de un cierre: Una función interior. (2)

Lo que depara el futuro

Definidas en ECMA Script 6 , las funciones de flecha adoptan el thisenlace desde el ámbito adjunto (función o global).

function foo() { // return an arrow function return (a) => { // `this` here is lexically inherited from `foo()` console.log(this.a); }; } var obj1 = { a: 2 }; var obj2 = { a: 3 }; var bar = foo.call(obj1); bar.call( obj2 ); // 2, not 3!

Si bien las funciones de flecha proporcionan una alternativa al uso bind(), es importante tener en cuenta que esencialmente están inhabilitando el thismecanismo tradicional en favor de un alcance léxico más comprendido. (1)

Referencias:

  1. esto y prototipos de objetos , por Kyle Simpson. © 2014 Getify Solutions.
  2. javascriptissexy.com - http://goo.gl/pvl0GX
  3. Angus Croll - http://goo.gl/Z2RacU

este uso para Scope como este

<script type="text/javascript" language="javascript"> $(''#tbleName tbody tr'').each(function{ var txt=''''; txt += $(this).find("td").eq(0).text(); //same as above but synatx different var txt1=''''; txt1+=$(''#tbleName tbody tr'').eq(0).text(); alert(txt1) }); </script>

el valor de txt1 y txt es igual en el ejemplo anterior $ (this) = $ (''# tbleName tbody tr'') es igual


¿A qué ayudaría quirksmode.org/js/this.html ? (La mayor parte de la confusión de ''esto'' en javascript proviene del hecho de que generalmente no está vinculado a su objeto, sino al ámbito de ejecución actual, que puede que no sea exactamente la forma en que funciona, pero siempre se siente así para mí. ver el artículo para una explicación completa)


Cada contexto de ejecución de función en javascript tiene un contexto de alcance, este parámetro está establecido por:

  1. Cómo se llama la función (incluido como método de objeto, uso de call y apply , uso de nuevo )
  2. Uso de enlace
  3. Léxicamente para funciones de flecha (adoptan esto de su contexto de ejecución externo)

Cualquiera que sea el contexto de alcance, está referenciado por "esto".

Puede cambiar el valor de este contexto de alcance usando , o .func.callfunc.applyfunc.bind

De forma predeterminada, y lo que confunde a la mayoría de los principiantes, cuando se llama a un detector de devolución de llamada después de que se genera un evento en un elemento DOM, el contexto de alcance de este valor de la función es el elemento DOM.

jQuery hace que esto sea trivial para cambiar con jQuery.proxy.


Daniel, impresionante explicación! Un par de palabras sobre esta y una buena lista de thispunteros de contexto de ejecución en caso de manejadores de eventos.

En dos palabras, thisen JavaScript señala el objeto desde el cual (o desde cuyo contexto de ejecución) se ejecutó la función actual y siempre es de solo lectura, no puede configurarlo de todos modos (tal intento terminará con ''Mano izquierda no válida Lado en el mensaje de asignación.

Para los manejadores de eventos: los manejadores de eventos en línea, como <element onclick="foo">anular cualquier otro manejador adjunto anteriormente y antes, así que tenga cuidado y es mejor evitar la delegación de eventos en línea. Y gracias a Zara Alaverdyan, que me inspiró a esta lista de ejemplos a través de un debate disidente :)

  • el.onclick = foo; // in the foo - obj
  • el.onclick = function () {this.style.color = ''#fff'';} // obj
  • el.onclick = function() {doSomething();} // In the doSomething - Window
  • el.addEventListener(''click'',foo,false) // in the foo - obj
  • el.attachEvent(''onclick, function () { // this }'') // window, all the compliance to IE :)
  • <button onclick="this.style.color = ''#fff'';"> // obj
  • <button onclick="foo"> // In the foo - window, but you can <button onclick="foo(this)">

El valor de "esto" depende del "contexto" en el que se ejecuta la función. El contexto puede ser cualquier objeto o el objeto global, es decir, la ventana.

Así que la Semántica de "esto" es diferente de los lenguajes tradicionales OOP. Y causa problemas: 1. cuando una función se pasa a otra variable (lo más probable, una devolución de llamada); y 2. cuando se invoca un cierre desde un método miembro de una clase.

En ambos casos, esto se establece en ventana.


En términos pseudoclásicos, la forma en que muchas conferencias enseñan la palabra clave ''this'' es como un objeto creado por una clase o un constructor de objetos. Cada vez que se construye un nuevo objeto a partir de una clase, imagine que bajo el capó se crea y devuelve una instancia local de un objeto ''this''. Recuerdo que enseñaba así:

function Car(make, model, year) { var this = {}; // under the hood, so to speak this.make = make; this.model = model; this.year = year; return this; // under the hood } var mycar = new Car(''Eagle'', ''Talon TSi'', 1993); // ========= under the hood var this = {}; this.make = ''Eagle''; this.model = ''Talon TSi''; this.year = 1993; return this;


Es difícil tener un buen conocimiento de JS, o escribir más que cualquier cosa trivial, si no lo entiendes bien. No puede darse el lujo de darse un baño rápido :) Creo que la mejor manera de comenzar con JS es ver primero estas conferencias de video de Douglas Crockford - http://yuiblog.com/crockford/ , que cubre esto y aquello, Todo lo demás sobre JS.


Esta es la mejor explicación que he visto. Entender JavaScripts esto con claridad

El esta referencia se refiere a SIEMPRE (y mantiene el valor de) un objeto-a singular objeto-y se utiliza por lo general dentro de una función o un método, aunque se puede utilizar fuera de una función en el ámbito global. Tenga en cuenta que cuando usamos el modo estricto, esto mantiene el valor de indefinido en funciones globales y en funciones anónimas que no están vinculadas a ningún objeto.

Hay cuatro condiciones donde esto puede ser confuso:

  1. Cuando pasamos un método (que usa esto ) como un parámetro para ser usado como una función de devolución de llamada.
  2. Otra instancia en la que esto se malinterpreta es cuando usamos un método interno (un cierre). Es importante tener en cuenta que los cierres no pueden acceder a la función externa de esta variable mediante el uso de esta palabra clave porque esta variable es accesible solo por la función en sí, no por las funciones internas.
  3. Usando esto cuando se asigna un método a una variable. El valor de este está vinculado a otro objeto, si asignamos un método que usa esto a una variable
  4. Usando esto al usar los métodos de enlazar, aplicar y llamar.

Da ejemplos de código, las explicaciones y las correcciones de código que me parecieron muy útiles.


Existe mucha confusión con respecto a cómo se interpreta la palabra clave "this" en JavaScript. Esperemos que este artículo ponga a todos a descansar de una vez por todas. Y mucho más. Por favor, lea todo el artículo cuidadosamente. Tenga en cuenta que este artículo es largo.

Independientemente del contexto en el que se usa, "esto" siempre hace referencia al "objeto actual" en Javascript. Sin embargo, el "objeto actual" difiere según el contexto . El contexto puede ser exactamente 1 de los 6 siguientes:

  1. Global (es decir, fuera de todas las funciones)
  2. Llamada interna directa de " función no vinculada " (es decir, una función que no se ha vinculado al llamar a functionName.bind )
  3. Llamada interna indirecta "Función no vinculada" a través de functionName.call y functionName.apply
  4. Dentro de la llamada "Función enlazada " (es decir, una función que se ha enlazado al llamar a functionName.bind )
  5. Si bien la creación de objetos a través de "nuevo"
  6. Controlador de eventos Inside Inline DOM

Lo siguiente describe cada uno de estos contextos uno por uno:

  1. Contexto global (es decir, fuera de todas las funciones):

    Fuera de todas las funciones (es decir, en el contexto global), el "objeto actual" (y, por lo tanto, el valor de "este" ) es siempre el objeto "ventana" para los navegadores.

  2. Llamada "Función no vinculada" directa interna :

    Dentro de una llamada directa de "función no vinculada" directa, el objeto que invocó la llamada de función se convierte en el "objeto actual" (y, por lo tanto, el valor de "este" ). Si se llama a una función sin un objeto actual explícito , el objeto actual es el objeto "ventana" (para el modo no estricto) o indefinido (para el modo estricto). Cualquier función (o variable) definida en el contexto global se convierte automáticamente en una propiedad del objeto "ventana". Por ejemplo, la función Suppose se define en el contexto global como

    function UserDefinedFunction(){ alert(this) }

    se convierte en propiedad del objeto de ventana, como si lo hubiera definido como

    window.UserDefinedFunction=function(){ alert(this) }

    En el "Modo no estricto", Llamar / Invocar esta función directamente a través de "UserDefinedFunction ()" automáticamente lo llamará / invocará como "window.UserDefinedFunction ()" making "window" como el "objeto actual" (y por lo tanto el valor de " este " ) dentro de " UserDefinedFunction ". Invocar esta función en" Modo no estricto "resultará en lo siguiente

    UserDefinedFunction() // displays [object Window] as it automatically gets invoked as window.UserDefinedFunction()

    En "Modo estricto", Calling / invocación de la función directamente a través de "UserDefinedFunction ()" será "NO" llamar automáticamente / invocar como "window.UserDefinedFunction ()" .Hence el "objeto actual" (y el valor de "este" ) dentro de "UserDefinedFunction" será indefinido . Invocar esta función en "Modo estricto" dará como resultado lo siguiente

    UserDefinedFunction() // displays undefined

    Sin embargo, invocarlo explícitamente usando el objeto de ventana dará como resultado lo siguiente:

    window.UserDefinedFunction() // "always displays [object Window] irrespective of mode."

    Veamos otro ejemplo. Por favor mira el siguiente código

    function UserDefinedFunction() { alert(this.a + "," + this.b + "," + this.c + "," + this.d) } var o1={ a:1, b:2, f:UserDefinedFunction } var o2={ c:3, d:4, f:UserDefinedFunction } o1.f() // Shall display 1,2,undefined,undefined o2.f() // Shall display undefined,undefined,3,4

    En el ejemplo anterior, vemos que cuando se invocó "UserDefinedFunction" a través de o1 , "this" toma el valor de o1 y el valor de sus propiedades "a" y "b" se muestran. El valor de "c" y "d" se mostraron como no definidos ya que o1 no define estas propiedades

    Del mismo modo, cuando "UserDefinedFunction" fue invocada a través de o2 , "este" toma el valor de O2 y el valor de sus propiedades "c" y "d" obtener displayed.The valor de "a" y "b" se muestra como indefinido como o2 hace No define estas propiedades.

  3. Llamada interna indirecta "Función no vinculada" a través de functionName.call y functionName.apply :

    Cuando se llama a una "función no vinculada" a través de functionName.call o functionName.apply , el "objeto actual" (y, por tanto, el valor de "this" ) se establece en el valor de "this" parámetro (primer parámetro) pasado a la llamada / aplicar . El siguiente código demuestra lo mismo.

    function UserDefinedFunction() { alert(this.a + "," + this.b + "," + this.c + "," + this.d) } var o1={ a:1, b:2, f:UserDefinedFunction } var o2={ c:3, d:4, f:UserDefinedFunction } UserDefinedFunction.call(o1) // Shall display 1,2,undefined,undefined UserDefinedFunction.apply(o1) // Shall display 1,2,undefined,undefined UserDefinedFunction.call(o2) // Shall display undefined,undefined,3,4 UserDefinedFunction.apply(o2) // Shall display undefined,undefined,3,4 o1.f.call(o2) // Shall display undefined,undefined,3,4 o1.f.apply(o2) // Shall display undefined,undefined,3,4 o2.f.call(o1) // Shall display 1,2,undefined,undefined o2.f.apply(o1) // Shall display 1,2,undefined,undefined

    El código anterior muestra claramente que el valor de "este" para cualquier "función no vinculada" puede modificarse mediante call / apply . Además, si el parámetro "this" no se pasa explícitamente a call / apply , "objeto actual" (y, por lo tanto, el valor de "this") se establece en "window" en modo no estricto y "indefinido" en modo estricto.

  4. Dentro de la llamada "Función enlazada " (es decir, una función que se ha enlazado al llamar a functionName.bind ):

    Una función enlazada es una función cuyo valor "esto" se ha corregido. El siguiente código demostró cómo "esto" funciona en caso de función vinculada

    function UserDefinedFunction() { alert(this.a + "," + this.b + "," + this.c + "," + this.d) } var o1={ a:1, b:2, f:UserDefinedFunction, bf:null } var o2={ c:3, d:4, f:UserDefinedFunction, bf:null } var bound1=UserDefinedFunction.bind(o1); // permanantly fixes "this" value of function "bound1" to Object o1 bound1() // Shall display 1,2,undefined,undefined var bound2=UserDefinedFunction.bind(o2); // permanantly fixes "this" value of function "bound2" to Object o2 bound2() // Shall display undefined,undefined,3,4 var bound3=o1.f.bind(o2); // permanantly fixes "this" value of function "bound3" to Object o2 bound3() // Shall display undefined,undefined,3,4 var bound4=o2.f.bind(o1); // permanantly fixes "this" value of function "bound4" to Object o1 bound4() // Shall display 1,2,undefined,undefined o1.bf=UserDefinedFunction.bind(o2) // permanantly fixes "this" value of function "o1.bf" to Object o2 o1.bf() // Shall display undefined,undefined,3,4 o2.bf=UserDefinedFunction.bind(o1) // permanantly fixes "this" value of function "o2.bf" to Object o1 o2.bf() // Shall display 1,2,undefined,undefined bound1.call(o2) // Shall still display 1,2,undefined,undefined. "call" cannot alter the value of "this" for bound function bound1.apply(o2) // Shall still display 1,2,undefined,undefined. "apply" cannot alter the value of "this" for bound function o2.bf.call(o2) // Shall still display 1,2,undefined,undefined. "call" cannot alter the value of "this" for bound function o2.bf.apply(o2) // Shall still display 1,2,undefined,undefined."apply" cannot alter the value of "this" for bound function

    Como se indica en el código anterior, "este" valor para cualquier "Función enlazada" NO SE PUEDE alterar a través de call / apply . Además, si el parámetro "esto" no se pasa explícitamente a vincular, el "objeto actual" (y, por lo tanto, el valor de "esto" ) se establece en "ventana" en el modo no estricto y "no definido" en el modo estricto. Una cosa más. El enlace de una función ya enlazada no cambia el valor de "esto" . Permanece establecido como el valor establecido por la primera función de enlace.

  5. Si bien la creación de objetos a través de "nuevo" :

    Dentro de una función constructora, el "objeto actual" (y, por tanto, el valor de "este" ) hace referencia al objeto que se está creando actualmente a través de "nuevo" independientemente del estado de enlace de la función. Sin embargo, si el constructor es una función vinculada, se llamará con un conjunto predefinido de argumentos según lo establecido para la función vinculada.

  6. Dentro del controlador de eventos Inline DOM :

    Por favor, mire el siguiente fragmento de código HTML

    <button onclick=''this.style.color=white''>Hello World</button> <div style=''width:100px;height:100px;'' onclick=''OnDivClick(event,this)''>Hello World</div>

    El "esto" en los ejemplos anteriores se refiere al elemento "botón" y al elemento "div" respectivamente.

    En el primer ejemplo, el color de fuente del botón se establecerá en blanco cuando se haga clic en él.

    En el segundo ejemplo, cuando se hace clic en el elemento "div" , se llamará a la función OnDivClick y su segundo parámetro hará referencia al elemento div en el que se hizo clic. Sin embargo, el valor de "esto" en OnDivClick NO DEBE hacer referencia al elemento div en el que se hizo clic . Se establecerá como "objeto de ventana" o "indefinido" en los modos no estricto y estricto respectivamente (si OnDivClick es una función independiente ) o se establecerá en un valor de límite predefinido (si OnDivClick es una función vinculada )

A continuación se resume todo el artículo.

  1. En el contexto global, "esto" siempre se refiere al objeto "ventana"

  2. Cuando se invoca una función, se invoca en el contexto de un objeto ( "objeto actual" ). Si el objeto actual no se proporciona explícitamente, el objeto actual es el "objeto de ventana" en el Modo NO Estricto y "no definido" en el Modo Estricto de manera predeterminada.

  3. El valor de "esto" dentro de una función no vinculada es la referencia al objeto en el contexto de la cual se invoca la función ( "objeto actual" )

  4. El valor de "esto" dentro de una función no vinculada puede ser anulado por los métodos de llamada y aplicación de la función.

  5. El valor de "esto" es fijo para una función enlazada y no puede ser anulado por los métodos de llamada y aplicación de la función.

  6. La función de vinculación y ya enlazada no cambia el valor de "esto". Permanece establecido como el valor establecido por la primera función de enlace.

  7. El valor de "esto" dentro de un constructor es el objeto que se está creando e inicializando.

  8. El valor de "esto" dentro de un controlador de eventos DOM en línea es referencia al elemento para el cual se proporciona el controlador de eventos.


Probablemente el artículo más detallado y completo sobre thises el siguiente:

Explicación suave de la palabra clave ''this'' en JavaScript

La idea subyacente thises comprender que los tipos de invocación de funciones tienen una importancia significativa en la configuración del thisvalor.

Cuando tengas problemas para identificarte this, no te preguntes:

¿De dónde se thistoma ?

pero no preguntarse:

¿Cómo se invoca la función ?

Para una función de flecha (caso especial de transparencia de contexto) pregúntese:

¿Qué valor tiene thisdonde se define la función de flecha ?

Esta mentalidad es correcta cuando se trata con thisy te salvará del dolor de cabeza.


Un poco de información sobre esta palabra clave.

Registremos la thispalabra clave en la consola en el ámbito global sin más código, pero

console.log(this)

En la palabra clave Cliente / Navegador this es un objeto global que eswindow

console.log(this === window) // true

y

En el servidor / Nodo / Javascript, la this palabra clave de tiempo de ejecución también es un objeto global que esmodule.exports

console.log(this === module.exports) // true console.log(this === exports) // true

Tener en cuenta exportses sólo una referencia amodule.exports