Descripción conceptual esto
Cuando se crea una función, una palabra clave que se crea (en segundo plano), que está vinculada a un objeto, y la función funciona en este objeto. En otras palabras, la palabra clave esto se puede usar en una función, una referencia a un objeto, y la función es la propiedad o el método de ese objeto.
Veamos este objeto:
<! DocType html> <html lang = "en"> <body> <script> var code = {Living: true, edad: 23, género: 'masculino', getgender: function () {return cody.gender;}}; console.log (cody.getgender ()); // registros 'masculino' </script> </body> </html>Tenga en cuenta que en la función GetGender, ya que dentro del objeto Cody, podemos obtener el atributo de género (es decir, Cody.Gender). También puede usar esto para obtener el objeto Cody, porque esto apunta al objeto Cody.
<! DocType html> <html lang = "en"> <body> <script> var code = {Living: true, edad: 23, género: 'masculino', getgender: function () {return this.gender;}}; console.log (cody.getgender ()); // registros 'masculino' </script> </body> </html>En esto.
El tema sobre esto puede ser un poco confuso, pero no tiene por qué serlo. Solo recuerde que, por lo general, el objeto que señala es el objeto que contiene la función, no la función en sí (por supuesto, hay excepciones, como usar las palabras clave new o llamar () y aplicar ())).
Consejos importantes
- La palabra clave es como otras variables, la única diferencia es que no puede cambiarla.
- A diferencia de otros parámetros y variables pasadas a una función, esta es una palabra clave (no una propiedad) en el objeto que llama a la función.
¿Cómo determinar el valor de esto?
Esto se pasa a todas las funciones, y su valor depende de cuándo se llama la función cuando se ejecuta. Tenga en cuenta aquí, porque este es un lugar muy especial que debe recordar.
En el siguiente código, el objeto MyObject tiene una propiedad que dice, que apunta a la función, dice. Cuando se llama a la función Sayfoo en el dominio global, esto apunta al objeto de la ventana. Cuando MyObject llama a una función, esto apunta a MyObject.
Debido a que MyObject tiene una propiedad llamada Foo, se usa aquí.
<! DocType html> <html lang = "en"> <body> <script> var foo = 'foo'; var myObject = {foo: 'Soy myobject.foo'}; var sayfoo = function () {console.log (this ['foo']); }; // Dale a MyObject una propiedad Sayfoo y que apunte a decir la función myObject.sayfoo = sayfoo; myObject.sayfoo (); // registros 'soy myobject.foo' 12 sayfoo (); // registros 'foo' </script> </body> </html>Está claro que el valor de esto depende de cuándo se llama a la función. myobject.sayfoo y Sayfoo apuntan a la misma función, pero el contexto de la llamada sayfoo () es diferente, por lo que el valor de esto es diferente. A continuación se muestra un código similar, el objeto de cabeza (ventana) se usa explícitamente, con la esperanza de que sea útil para usted.
<! DocType html> <html lang = "en"> <body> <script> window.foo = 'foo'; Window.myObject = {foo: 'Soy myobject.foo'}; Window.sayfoo = function () {! console.log (this.foo); }; Window.myobject.sayfoo = Window.sayfoo; Window.MyObject.sayfoo (); Window.sayfoo (); </script> </body> </html>Asegúrese de que cuando tenga múltiples referencias que apunten a la misma función, sabe claramente que el valor de este cambio dependiendo del contexto de la función de llamada.
Consejos importantes
- Todas las variables y parámetros, excepto esto, pertenecen al alcance de la variable estática.
Esto apunta al objeto de cabeza dentro de la función incrustada
Es posible que se pregunte qué sucede al usar esto en una función incrustada en otra función. Desafortunadamente en el ECMA 3, esto no sigue las reglas, no apunta al objeto donde pertenece la función, sino al objeto principal (el objeto de la ventana del navegador).
En el siguiente código, esto en Func2 y Func3 ya no apunta a MyObject, sino al objeto principal.
<! DocType html> <html lang = "en"> <body> <script> var myObject = {func1: function () {console.log (this); // registra myObject varfunc2 = function () {console.log (this); // La ventana registra, y lo hará desde este punto en varfunc3 = function () {console.log (this); // Ventana de registro, ya que es el objeto de cabeza} (); } (); }}; myObject.func1 (); </script> </body> </html>Sin embargo, en Ecmascript 5, este problema se corregirá. Ahora debe ser consciente de este problema, especialmente cuando pasa el valor de una función a otra.
Mire el código a continuación, pase una función anónima a foo.func1. Cuando se llama a una función anónima en foo.func1 (la función está anidada en otra función), esto apuntará al objeto de cabeza en la función anónima.
<! DocType html> <html lang = "en"> <body> <script> var foo = {func1: function (bar) {bar (); // Ventana de registros, no Foo Console.log (this); // La palabra clave aquí será una referencia al objeto foo}}; foo.func1 (function () {console.log (this)}); </script> </body> </html>Ahora no olvidará que si la función que contiene esto está en otra función, o se llama por otra función, el valor de esto apuntará al objeto de cabeza (nuevamente, esto se corregirá en Ecmascript 5.)
Resolver el problema de las funciones anidadas
Para evitar que esto se pierda, puede usar una cadena de alcance en la función principal para ahorrar referencias a esto. En el siguiente código, utilizando una variable llamada así, usando su alcance, podemos guardar mejor el contexto de la función.
<! DocType html> <html lang = "en"> <body> <script> var myObject = {myProperty: 'icanseeHelight', mymethod: function () {var that = this; // Almacene una referencia a esta (iemyObject) en mymethod alcance varhelperfunction function () {// infunción var de la función helperfunction () {// infunción infantil // registra 'puedo ver la luz' a través de la cadena de alcance porque eso = este console.log (que.myPerty); // registros 'puedo ver la luz' console.log (esto); // registra objeto de ventana, si no usamos "eso"} (); }} myObject.MyMethod (); // Invoca mymethod </script> </body> </html>Controlar el valor de este
El valor de esto generalmente depende del contexto en el que se llame la función (a menos que se use la palabra clave nueva, que se introducirá más adelante), pero puede usar Apply () o llamar () para especificar el objeto con el que esto apunta cuando se desencadena una función para cambiar/controlar el valor de esto. Usar estos dos métodos es como decir nuevamente: "Hola, llame a la función X, pero deje que el objeto Z haga este valor". Al hacerlo, se cambiará el valor predeterminado de este JavaScript.
A continuación, creamos un objeto y una función, y luego activamos la función a través de la llamada (), por lo que esto en la función apunta a myojbect. Esto en la función de MyFunction funciona en MyObject en lugar del objeto de cabeza, por lo que cambiamos el objeto señalado por esto en MyFunction.
<! DocType html> <html lang = "en"> <body> <script> var myObject = {}; var myfunction = function (param1, param2) {// setViacall () 'this'foints a mi objeto cuando la función se invoca this.foo = param1; this.Bar = param2; console.log (esto); // objeto de registro {foo = 'foo', bar = 'bar'}}; myfunction.call (myobject, 'foo', 'bar'); // Invoca la función, configure este valor en myObject console.log (myObject) // logs object {foo = 'foo', bar = 'bar'} </script> </body> </html>En el ejemplo anterior, utilizamos Call (), Aplicar () también se puede aplicar al mismo uso. La diferencia entre los dos es cómo se pasan los parámetros a la función. Use llamada (), los parámetros están separados por comas y aplican (), y los parámetros se pasan en una matriz. El siguiente es el mismo código, pero use Aplicar ().
<! DocType html> <html lang = "en"> <body> <script> var myObject = {}; var myfunction = function (param1, param2) {// set a través de aplicado (), esto apunta a mi objeto cuando la función se invoca this.foo = param1; this.Bar = param2; console.log (esto); // objeto de registro {foo = 'foo', bar = 'bar'}}; myfunction.apply (myobject, ['foo', 'bar']); // Invocar la función, establecer este valor console.log (myObject); // registra objeto {foo = 'foo', bar = 'bar'} </script> </body> </html>Use esto en un constructor personalizado
Cuando la función se activa con la palabra clave nueva, el valor de esto se declara en el constructor para señalar la instancia misma. En otras palabras: en el constructor, podemos usar esto para especificar el objeto antes de que realmente se cree. Esto parece cambiar este valor para llamar () o aplicar ().
A continuación, construimos una persona constructora, que apunta al objeto creado. Cuando se crea el objeto de la persona, esto apunta a este objeto y coloca el nombre de la propiedad en el objeto, y el valor es el valor del parámetro (nombre) pasado a este constructor.
<! DocType html> <html lang = "en"> <body> <script> var persona = function (name) {this.name = name || 'Johndoe'; // Esto se referirá al instante creado} var Code = New Person ('Cody Lindley'); // crear una instancia, basada en la persona Constructor Console.log (cody.name); // registros 'Cody Lindley' </script> </body> </html>De esta manera, cuando el constructor se activa con la palabra clave nueva, esto apunta a "objeto que se creará". Entonces, si no usamos la palabra clave nueva, el valor de esto apuntará al contexto que desencadena a la persona: este es el objeto principal. Echemos un vistazo al código a continuación.
<! DocType html> <html lang = "en"> <body> <script> var persona = function (name) {this.name = name || 'Johndoe'; } var Code = Person ('Cody Lindley'); // Observe que no usamos 'nuevo' console.log (cody.name); // Undefined, el valor realmente se establece en Window.Name Console.log (Window.name); // registros 'Cody Lindley' </script> </body> </html>Esto apunta a la instancia del constructor dentro del método prototipo
Cuando se utiliza un método como propiedad prototipo de un constructor, esto en este método apunta a una instancia del método de activación. Aquí, tenemos un constructor persona (), que requiere el nombre completo de la persona. Para obtener el nombre completo, agregamos un método WhatIsmyfullName a la persona. Prototipo, y todas las instancias de la persona heredan este método. Esto en este método apunta a la instancia (y sus propiedades) que desencadenaron este método.
A continuación, creé dos objetos de persona (Cody y Lisa), y el método heredado de WhatImtMyfullName contiene este punto para esta instancia.
<! DocType html> <html lang = "en"> <body> <script> var persona = function (x) {if (x) {this.fullName = x}; }; Persona.prototype.whatismyfullName = function () {return this.fullName; // 'esto' se refiere a la instancia creada a partir de persona ()} var Code = New Person ('Cody Lindley'); var lisa = nueva persona ('Lisa Lindley'); // llamar al método heredado de WhatImSyfullName, que usa esto para referirse a la instancia console.log (cody.whatismyfullName (), lisa.whatismyfullName ()); /* La cadena prototipo todavía está vigente, por lo que si la instancia no tiene una propiedad de nombre completo, la buscará en la cadena prototipo. A continuación, agregamos una propiedad de nombre completo tanto al prototipo de persona como al prototipo de objeto. Ver notas. */Objeto.prototype.fullName = 'John Doe'; var John = nueva persona (); // No se pasa ningún argumento, por lo que no se agrega FullName a instancias console.log (John.whatismyfullName ()); // Registros 'John Doe' </script> </body> </html>Use esto en el método dentro del objeto prototipo, y esto apunta a la instancia. Si la instancia no contiene atributos, comienza la búsqueda del prototipo.
pista
- Si el objeto señalado a esto no contiene los atributos que desea encontrar, entonces la ley que se aplica a cualquier atributo también es aplicable aquí, es decir, los atributos se "buscarán" a lo largo de la cadena prototipo. Entonces, en nuestro ejemplo, si la instancia no contiene la propiedad FullName, entonces el nombre completo buscará persona.prototype.fullname y luego objeto.prototype.fullName.
Para ver más sintaxis de JavaScript, puede seguir: "Tutorial de referencia de JavaScript" y "Guía de estilo de código JavaScript". También espero que todos apoyen más a Wulin.com.