El uso de métodos de instancia como devoluciones de llamada para los controladores de eventos cambia el alcance de thisde "Mi ejemplo" a "Lo que acaba de llamar la devolución de llamada" . Entonces mi código se ve así
function MyObject() {
  this.doSomething = function() {
    ...
  }
  var self = this
  $('#foobar').bind('click', function(){
    self.doSomethng()
    // this.doSomething() would not work here
  })
}Funciona, pero ¿es esa la mejor manera de hacerlo? Me parece extraño
                    
                        javascript
                                jquery
                                scope
                                closures
                                
                    
                    
                        difunto
fuente
                
                fuente

selfya que hay unwindow.selfobjeto y podría terminar usándolo accidentalmente si olvida declarar su propiaselfvar (por ejemplo, cuando mueve algún código). Esto puede ser molesto para detectar / depurar. Es mejor usar algo como_this.thises dinámico en JavaScript. Se determina cuando se llama a la función , no cuando se declara".self === this. Por lo tanto,selfen contextos locales tiene sentido y sigue el patrón.Respuestas:
Esta pregunta no es específica de jQuery, sino específica de JavaScript en general. El problema central es cómo "canalizar" una variable en funciones integradas. Este es el ejemplo:
Esta técnica se basa en el uso de un cierre. Pero no funciona
thisporquethises una pseudo variable que puede cambiar de un alcance a otro dinámicamente:¿Qué podemos hacer? Asignarlo a alguna variable y usarlo a través del alias:
thisno es único a este respecto:argumentses la otra pseudo variable que debe tratarse de la misma manera, mediante alias.fuente
Sí, esto parece ser un estándar común. Algunos codificadores se usan a sí mismos, otros me usan a mí. Se utiliza como referencia de regreso al objeto "real" en lugar del evento.
Es algo que me tomó un poco de tiempo entender, al principio parece extraño.
Por lo general, hago esto justo en la parte superior de mi objeto (disculpe mi código de demostración, es más conceptual que cualquier otra cosa y no es una lección sobre una excelente técnica de codificación):
fuente
editar: a pesar de, las funciones anidadas dentro de un objeto toman el objeto de la ventana global en lugar del objeto circundante.
fuente
var self = thishace, pero eso no es lo que la pregunta está haciendo (la pregunta es si esa es la mejor solución al problema).Si está haciendo ES2015 o está haciendo script de tipo y ES5, entonces puede usar funciones de flecha en su código y no enfrenta ese error y esto se refiere al alcance deseado en su instancia.
fuente
thisdesde su alcance definitorio. Las definiciones de funciones normales no hacen eso.Una solución a esto es vincular toda su devolución de llamada a su objeto con el
bindmétodo de JavaScript .Puedes hacer esto con un método con nombre,
O con una devolución de llamada anónima
Hacer esto en lugar de recurrir a
var self = thismuestra que comprende cómo sethiscomporta el enlace de javascript y no se basa en una referencia de cierre.Además, el operador de flecha gruesa en ES6 básicamente es lo mismo que invocar
.bind(this)una función anónima:fuente
No he usado jQuery, pero en una biblioteca como Prototype puede vincular funciones a un ámbito específico. Entonces, con eso en mente, su código se vería así:
El método de enlace devuelve una nueva función que llama al método original con el alcance que ha especificado.
fuente
$('#foobar').ready('click', this.doSomething.call(this));¿verdad?bindmétodo no funciona en navegadores antiguos, por lo tanto, utilice el$.proxymétodo.Simplemente agregue a esto que en ES6 debido a las funciones de flecha, no debería necesitar hacer esto porque capturan el
thisvalor.fuente
Creo que en realidad depende de qué vas a hacer dentro de tu
doSomethingfunción. Si va a acceder a lasMyObjectpropiedades usando esta palabra clave, entonces debe usarla. Pero creo que el siguiente fragmento de código también funcionará si no está haciendo cosas especiales usandoobject(MyObject)propiedades.fuente