PDF de programación - This & Object Prototypes

Imágen de pdf This & Object Prototypes

This & Object Prototypesgráfica de visualizaciones

Publicado el 02 de Octubre del 2018
186 visualizaciones desde el 02 de Octubre del 2018. Una media de 35 por semana
485,4 KB
140 paginas
Creado hace 108d (29/07/2018)
THIS & OBJECT PROTOTYPES: Kyle Simpson

1. this or that? (esto o aquello?)

Uno de los mecanismos más confusos en JavaScript es la palabra clave this. Es
una palabra clave de identificación especial que se define automáticamente en
el ámbito de cada función.

Cualquier tecnología suficientemente avanzada es indistinguible de la magia. --
Arthur C. Clarke
El mecanismo de Javascript this no es realmente tan avanzado, pero los
desarrolladores a menudo parafrasean esa cita en su propia mente insertando
"complejo" o "confuso", y no hay duda de que sin falta de comprensión clara, this
puede parecer francamente mágico entre su confusión.

Nota: La palabra "this" es un pronombre terriblemente común en el discurso
general. Por lo tanto, puede ser muy difícil, especialmente verbalmente, determinar
si estamos usando "esto" como pronombre o si lo estamos usando para referirnos al
identificador real de la palabra clave. Para mayor claridad, siempre usaré this para
referirme a la palabra clave especial, y "esto" o esto para los otros.

¿Por qué this?
Si el mecanismo this es tan confuso, incluso para desarrolladores JavaScript
experimentados, uno puede preguntarse por qué es tan útil. ¿Ocasiona más
problemas que benefícios? Antes de entrar en el cómo, debemos examinar el por
qué.

Tratemos de ilustrar la motivación y la utilidad de this:

function identify() {
return this.name.toUpperCase();
}

function speak() {
var greeting = "Hello, I'm " + identify.call( this );
console.log( greeting );
}

var me = {
name: "Kyle"
};

var you = {
name: "Reader"
};

identify.call( me ); // KYLE
identify.call( you ); // READER
speak.call( me ); // Hello, I'm KYLE
speak.call( you ); // Hello, I'm READER
Si este fragmento te confunde, ¡no te preocupes! Llegaremos a eso pronto. Deje
esas preguntas a un lado brevemente para que podamos ver el por qué más
claramente.

Este fragmento de código permite que las funciones identify() y speak() sean
reutilizadas contra objetos de contexto múltiple (me y you), en lugar de necesitar
una versión separada de la función para cada objeto.

En lugar de confiar en this, podrías haber pasado explícitamente en un objeto
contextual tanto para identify() como para speak().

function identify(context) {
return context.name.toUpperCase();
}

function speak(context) {
var greeting = "Hello, I'm " + identify( context );
console.log( greeting );
}

identify( you ); // READER
speak( me ); // Hello, I'm KYLE
Sin embargo, el mecanismo this proporciona una forma más elegante de "pasar"
implícitamente una referencia a un objeto, lo que conduce a un diseño de API más
limpio y a una reutilización más fácil.

Cuanto más complejo sea su patrón de uso, más claramente verá que pasar el
contexto como un parámetro explícito es a menudo más complicado que pasar el
contexto this. Cuando exploeamos objetos y prototipos, verás la utilidad de una
colección de funciones que pueden hacer referencia automáticamente al objeto de
contexto apropiado.

Confusiones
Pronto empezaremos a explicar cómo realmente funciona this, pero primero
debemos disipar algunas conceptos erróneos sobre cómo no funciona en realidad.

El nombre "this" crea confusión cuando los desarrolladores tratan de pensar en ello
demasiado literalmente. Allí son dos significados a menudo asumidos, pero ambos
son incorrectos.

En sí mismo
La primera tentación común es asumir que this se refiere a la función misma. Eso
es un una inferencia gramatical razonable, al menos.

¿Por qué querría referirse a una función desde dentro de sí misma? Las razones
más comunes serían cosas como la recursión (llamar a una función desde dentro de
sí misma) o tener un evento que puede desatarse cuando se llama por primera vez.

Los desarrolladores nuevos en los mecanismos de JS a menudo piensan que hacer
referencia a la función como un objeto (todas las funciones en JavaScript son
objetos!) le permite almacenar el estado (valores en las propiedades) entre
llamadas de función. Si bien esto es ciertamente posible y tiene algunos usos
limitados, el resto del libro explicará muchos otros patrones con otros mejores
lugares para almacenar el estado además de la función objeto.

Pero por un momento, exploraremos el patrón, para ilustrar cómo this no deja que
una función obtenga una referencia a sí misma como podríamos haber asumido.

Considere el siguiente código, donde intentamos rastrear cuántas veces una
función ( foo ) es llamada:

function foo(num) {
console.log( "foo: " + num );

// keep track of how many times foo is called
this.count++;
}

foo.count = 0;

var i;

for (i=0; i<10; i++)="" {="" if="" (i=""> 5) {
foo( i );
}
}
// foo: 6
// foo: 7
// foo: 8

// foo: 9

// how many times was foo called?
console.log( foo.count ); // 0 -- WTF?
foo.count sigue siendo 0 , a pesar de que las cuatro sentencias console.log indican
claramente que foo(..) fue llamado cuatro veces. La frustración proviene de una
interpretación demasiado literal de lo que this (en this.count++) significa.

Cuando el código ejecuta foo.count = 0, de hecho está añadiendo una propiedad
count al objeto de función foo. Pero para la referencia this.count dentro de la
función, this de hecho no apunta en absoluto a ese objeto de función, así que
aunque los nombres de las propiedades son los mismos, los objetos raíz son
diferentes, y se produce confusión.

Nota: Un desarrollador responsable debe preguntar en este punto, "Si estaba
incrementando una propiedad count pero no era la que esperaba, ¿qué count
estaba incrementando?" De hecho, si cavara más profundo, se daría cuenta de que
accidentalmente había creado una variable count global (¡ver Capítulo 2 para ver
cómo sucedió!), y que actualmente tiene el valor NaN. Por supuesto, una vez que
identifica este resultado peculiar, tiene otra serie de preguntas: "¿Cómo fue global,
y por qué terminó siendo NaN en lugar de un valor de count apropiado?" (ver
Capítulo 2).

En lugar de detenerse en este punto y averiguar por qué esta referencia no parece
comportarse como se esperaba, y responder a esas preguntas difíciles pero
importantes, muchos desarrolladores simplemente evitan el problema por
completo, y hackean hacia alguna otra solución, como por ejemplo creando otro
objeto para sostener la propiedad count:

function foo(num) {
console.log( "foo: " + num );
// keep track of how many times foo is called
data.count++;
}

var data = {
count: 0
};

var i;

for (i=0; i<10; i++)="" {="" if="" (i=""> 5) {
foo( i );

}
}

// foo: 6
// foo: 7
// foo: 8
// foo: 9

// how many times was foo called?
console.log( data.count ); // 4
Si bien es cierto que este enfoque "resuelve" el problema, desafortunadamente
simplemente ignora el verdadero problema - la falta de comprensión de lo que this
significa y cómo funciona - y en su lugar vuelve a la zona de confort de un
mecanismo más familiar: el ámbito léxico.

Nota: El alcance léxico es un mecanismo perfectamente fino y útil; no estoy
menospreciando su uso, de ninguna manera (ver "scope & closures" en el título de
esta serie de libros). Pero adivinar constantemente cómo usar this y, por lo general,
estar equivocado, no es una buena razón para volver al ámbito léxico y nunca
aprender por qué this te elude.

Para hacer referencia a un objeto de función desde dentro de sí mismo, this por sí
mismo será normalmente insuficiente. Generalmente se necesita una referencia al
objeto de función mediante un identificador léxico (variable) que apunta a ello.

Considere estas dos funciones:

function foo() {
foo.count = 4; // foo refers to itself
}

setTimeout( function(){
// anonymous function (no name), cannot
// refer to itself
}, 10 );
En la primera función, llamada "función nombrada", foo es una referencia que
puede usarse para referirse a la función desde dentro de sí misma.

Pero en el segundo ejemplo, la función callback pasada a setTimeout(..) no tiene
ningún identificador de nombre (por lo que es llamada "función anónima"), así que
no hay una manera apropiada de referirse al objeto de función en sí.

Nota: La referencia de la vieja escuela arguments.callee dentro de una función

también apunta a la función objeto de la función que se está ejecutando
actualmente. Esta referencia es típicamente la única manera de acceder al objeto
de una función anónima desde su interior. El mejor enfoque, sin embargo, es evitar
el uso de funciones anónimas en su totalidad, al menos para aquellas que requieren
una auto-referencia, y en su lugar usar una función con nombre (expresión).
arguments.callee está obsoleto y no debería usarse.

Así que otra solución a nuestro ejemplo de ejecución habría sido usar el
identificador de foo como una referencia de objeto de función en cada lugar y no
utilizar this en absoluto, lo que funciona:

function foo(num) {
console.log( "foo: " + num );
// keep track of how many times foo is called
foo.count++;
}

foo.count = 0;

var i;
for (i=0; i<10; i++)="" {="" if="" (i=""> 5) {
foo( i );
}
}

// foo: 6
// foo: 7
// foo: 8
// foo: 9

// how many times was foo called?
console.log( foo.count ); // 4
Sin embargo, ese enfoque también deja de lado la comprensión real de this y se
basa enteramente en el alcance léxico de la variable foo.

Otra forma de enfocar la cuestión es obligar a que this apunte realmente al objeto
de función foo:

function foo(num) {
console.log( "foo: " + num );

// keep track of how many times foo is called
// Nota: this es actualmente foo ahora, debido a como foo is llamada (ver abajo)

this.count++;
}

foo.count = 0;

var i;
for (i=0; i<10; i++)="" {="" if="" (i=""> 5) {
// usando call(..) , nos aseguramos de que this apunta al objeto de función
( foo ) en sí mismo
foo.call( foo, i );
}
}

// foo: 6
// foo: 7
// foo: 8
// foo: 9

// how many times was foo called?
console.log( foo.count ); // 4
En lugar de evitar this, lo aceptamos. Explicaremos en un momento cómo estas
técnicas funcionan de manera mucho más completa, así que no te preocupes si
todavía estás un poco confundido.

Su Alcance
El sigui
  • Links de descarga
http://lwp-l.com/pdf13704  

Comentarios de: This & Object Prototypes (0)


No hay comentarios
 

Comentar...

Nombre
Correo (no se visualiza en la web)
Valoración
Comentarios
Es necesario revisar y aceptar las políticas de privacidad

Revisar política de publicidad