2009-06-16 19 views
10

Vengo de un fondo Java, con su modelo de herencia basado en clases, tratando de entender el modelo de herencia basado en prototipos de Javascript. Parte de lo que me está desanimando, creo que es que tengo en mente el significado de "esto" de Java, y el "esto" de Javascript es una bestia muy diferente. Entiendo que "esto" de Javascript siempre se refiere a la persona que llama a la función, no al ámbito en el que se definió la función. Es decir, lo he leído y entiendo superficialmente lo que significa. Pero me gustaría tener una comprensión más profunda, y creo que tener otro nombre podría ayudar. ¿Cómo piensas sobre JS "esto"? ¿Haces un reemplazo mental cada vez que te cruzas con él? Si es así, ¿qué palabra o frase usas?¿Cuál sería un nombre mejor para "esto" de Javascript?

+0

Al principio la pregunta parecía tonta, pero después de leer algunas respuestas, es bastante interesante en realidad ;-) +1 –

Respuesta

17

this podría ser renombrado razonablemente context en Javascript.

Es realmente refería a un contexto de ejecución del ámbito actual, y mientras ese contexto puede ser una instancia de una clase, desde luego, no tiene por qué ser — puede ser cualquier objeto en absoluto, y puede ser modificado en tiempo de ejecución.

La prueba de que no hay garantía alguna de que el "método" una en Javascript está operando en una instancia de la "clase" en el que se define:

function Cat(){ 

    this.texture = 'fluffy'; 

    this.greet = function(){ 
     alert("Pet me, I'm " + this.texture); 
    } 
} 

var cat = new Cat(); 

// Default to using the cat instance as the this pointer 
cat.greet(); // Alerts "Pet me, I'm fluffy" 

// Manually set the value of the this pointer! 
cat.greet.call({texture: 'scaly'}); // Alerts "Pet me, I'm scaly" 

Es importante tener en cuenta que hay que el valor del objeto this es completamente independiente de donde se define la función contenedora.

+0

Entonces, ¿es correcto decir que la palabra clave "this" permite emular el alcance dinámico en javascript ?. (En general, se dice que todas las funciones tienen un alcance léxico/estático) – techzen

5

Creo que this de JavaScript está mucho más cerca de Java this de lo que piensas. En un contexto de OOP, this significa "esta instancia". Creo que lo que puede ser confuso acerca de la palabra clave this de JavaScript es que puede tener significado diferente según el contexto.

+0

"esto" no siempre significa "esta instancia". Por ejemplo, puede establecer manualmente el valor de "this" para cualquier función usando Function.call o Function.apply. – Triptych

+0

Correcto, entonces "esto" significa "esta instancia" hasta que lo cambie. Eso no cambia el significado inicial de "esto".Entonces, ¿puedo suponer que estás de acuerdo conmigo en que "esto" es altamente contextual? –

+1

Realmente tiene que confiar en que 'esto' está siendo configurado correctamente por la persona que llama. Al igual que en object-c, confío en que 'self' es realmente la instancia actual. En Java, no puede cambiar "esto" para apuntar a otra cosa. – Kekoa

1

¿Qué tal "JavaScript esto"? Te mantendrá atado directamente a lo que estás haciendo y también proporcionará el recordatorio mental de que el concepto de "esto" con el que estás trabajando actualmente es el concepto de JavaScript.

Eventualmente, esperaría que dejaras de llamarlo 'JavaScript this' y simplemente lo llames 'esto', siendo totalmente consciente de lo que eso significa en el contexto en el que estás trabajando. Lo que esperaría es probablemente donde quiera llegar, de todos modos.

+0

Sí. Con disculpas al Zen: antes de haber aprendido Javascript, las montañas son montañas; las aguas son aguas Cuando aprendí Javascript, las montañas ya no eran montañas y aguas, ya no riegan. Una vez que dominaba Javascript, las montañas volvían a ser montañas y las aguas volvían a ser aguas. –

3

this no es la persona que llama de una función (aunque podría ser) o el ámbito en el que se define la función (aunque podría ser) - es contexto de la función.

El significado cambiante al que se refiere @Andrew Hare es probablemente más cercano al origen de su confusión; debido al mecanismo de herencia prototipo de JS, la palabra clave function puede significar, en función de cómo se usa, algo más cercano al class de Java que la definición del método de Java.

ejecución Suponiendo en el navegador:

var q = this.document; //this is window 

var o = new (function pseudoconstructor(){ 
    this.property = "something else" //the new keyword changed 'this' to mean 'the object I'm about to return' 
})(); 
9

Un posible nombre alternativo sería owner. Esto llevaría a su mente en la dirección en que el propietario puede cambiar según el código que esté ejecutando.

Este ejemplo es de quirksmode:

En JavaScript this siempre se refiere al “dueño” de la función que estamos ejecutando, o mejor dicho, al objeto de que una función es un método de. Cuando definimos nuestra función fiel doSomething() en una página, su propietario es la página, o más bien, el objeto de ventana (u objeto global) de JavaScript. Sin embargo, una propiedad onclick es propiedad del elemento HTML al que pertenece.

En el siguiente código,

function doSomething() { 
    this.style.color = '#cc0000'; 
} 

y

element.onclick = doSomething; 

, owner puntos en el objeto que contiene el método cuando se ejecuta.

------------ window -------------------------------------- 
|          /\   | 
|           |   | 
|           this   | 
| ----------------      |   | 
| | HTML element | <-- this   ----------------- | 
| ----------------  |   | doSomething() | | 
|    |   |   ----------------- | 
|   --------------------       | 
|   | onclick property |       | 
|   --------------------       | 
|              | 
---------------------------------------------------------- 
+1

No voté (todavía), pero no me gusta esta respuesta, porque lleva a creer que el valor de este puntero es "siempre" determinado por donde se define la función, lo cual es completamente falso. – Triptych

0

Absorbo novela sintaxis con pequeños modelos mentales fáciles de tipo tales como:

$(document).ready(function() { 

    function baffle() { 
    alert(this.b); 
    } 

    function what() { 
    this.b = "Hello"; 
    baffle(); 
    } 

    function huh() { 
    this.b = "World"; 
    baffle(); 
    } 

    what(); 
    huh(); 

    } 
); 

Este mal-se traduce en descuidado, C imaginaria ++ como:

template <class This> 
function baffle() { 
    alert(This.b); 
} 

function what() { 
    b = "Hello"; 
    baffle<what>(); 
} 

function huh() { 
    b = "World"; 
    baffle<huh>(); 
} 

what(); 
huh(); 
0

pienso this es el más apropiado por razones históricas. No existe realmente una frase única para this en JavaScript, ya que no solo se puede asignar automáticamente a referencias muy diferentes, por ejemplo, this en el contexto de una función de procedimiento o this en el contexto de un objeto , pero this también pueden ser asignados por el script usando Function.apply y Function.call.

Sin embargo, el significado de this solo se puede ajustar porque JavaScript y el DOM funcionan de maneras muy extrañas. Por ejemplo, el uso principal de Function.apply es preservar el contexto de una referencia de elemento en llamadas de evento. Habrá visto esto en el método Function.bind() de Prototye.

this es un marcador de posición para el contexto en el que se está ejecutando la función, y es difícil obtener algo más específico que eso. Sin embargo, la mayoría de los usos de this lo convierten en una palabra clave semánticamente apropiada. En el caso de bind(), aunque estamos utilizando métodos para cambiar arbitrariamente el significado de this dentro de la función, se debe usar para hacer que this sea más apropiado de lo que sería sin él. Muchos programadores de JavaScript aficionados son expulsados ​​por el extraño comportamiento de this en los controladores de eventos, y Function.apply se utiliza para corregir ese "error".

-1

La lógica autoreferencial (self o this) evita las paradojas a la ventaja de trabajar en otro que no sea el yo (esto). Si uno mismo (esto) mantiene todo y todo en uno, también puede permanecer estático sin instancia y con el método de clase (estático) en su lugar. Para evitar paradojas, evite las autorreferencias y la lógica mantiene todas las verdades demostrables y viceversa, todas las comprobaciones verdaderas.

Cuestiones relacionadas