una - tipos de scope javascript
var self=esto? (8)
Creo que realmente depende de qué vas a hacer dentro de tu función doSomething
. Si va a acceder a las propiedades de MyObject
usando esta palabra clave, entonces debe usar eso. Pero creo que el siguiente fragmento de código también funcionará si no está haciendo cosas especiales con las propiedades de object(MyObject)
.
function doSomething(){
.........
}
$("#foobar").ready(''click'', function(){
});
El uso de métodos de instancia como devoluciones de llamada para los manejadores de eventos cambia el alcance de this
de "Mi instancia" 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
Esta pregunta no es específica de jQuery, sino específica de JavaScript en general. El problema principal es cómo "canalizar" una variable en funciones incorporadas. Este es el ejemplo:
var abc = 1; // we want to use this variable in embedded functions
function xyz(){
console.log(abc); // it is available here!
function qwe(){
console.log(abc); // it is available here too!
}
...
};
Esta técnica se basa en el uso de un cierre. Pero no funciona con this
porque this
es una pseudovariable que puede cambiar dinámicamente de un alcance a otro:
// we want to use "this" variable in embedded functions
function xyz(){
// "this" is different here!
console.log(this); // not what we wanted!
function qwe(){
// "this" is different here too!
console.log(this); // not what we wanted!
}
...
};
¿Qué podemos hacer? Asignarlo a alguna variable y usarlo a través del alias:
var abc = this; // we want to use this variable in embedded functions
function xyz(){
// "this" is different here! --- but we don''t care!
console.log(abc); // now it is the right object!
function qwe(){
// "this" is different here too! --- but we don''t care!
console.log(abc); // it is the right object here too!
}
...
};
this
no es único a este respecto: arguments
es la otra pseudovariable que debe tratarse de la misma manera, mediante aliasing.
No he usado jQuery, pero en una biblioteca como Prototype puedes vincular funciones a un alcance específico. Entonces, teniendo esto en cuenta, su código sería así:
$(''#foobar'').ready(''click'', this.doSomething.bind(this));
El método bind devuelve una nueva función que llama al método original con el alcance que ha especificado.
Sí, esto parece ser un estándar común. Algunos codificadores usan uno mismo, otros me usan. Se usa como referencia para el objeto "real" en lugar del evento.
Es algo que me tomó un poco de tiempo realmente obtener, parece extraño al principio.
Usualmente hago esto directamente 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):
function MyObject(){
var me = this;
//Events
Click = onClick; //Allows user to override onClick event with their own
//Event Handlers
onClick = function(args){
me.MyProperty = args; //Reference me, referencing this refers to onClick
...
//Do other stuff
}
}
Si está haciendo ES2015 o haciendo script de tipo y ES5, puede usar las funciones de flecha en su código y no se enfrenta a ese error y esto se refiere al alcance deseado en su instancia.
this.name = ''test''
myObject.doSomething(data => {
console.log(this.name) // this should print out ''test''
});
Solo agregue a esto que en ES6 debido a las funciones de flecha no debería necesitar hacer esto porque capturan this
valor.
Una solución para esto es enlazar toda su devolución de llamada a su objeto con el método de vinculación de javascript.
Puedes hacer esto con un método nombrado,
function MyNamedMethod() {
// You can now call methods on "this" here
}
doCallBack(MyNamedMethod.bind(this));
O con una devolución de llamada anónima
doCallBack(function () {
// You can now call methods on "this" here
}.bind(this));
Hacer esto en lugar de recurrir a var self = this
muestra que usted entiende cómo se vincula el enlace de this
en javascript y no se basa en una referencia de cierre.
Además, el operador de flecha gordo en ES6 básicamente es lo mismo que llamar .bind(this)
en una función anónima:
doCallback( () => {
// You can reference "this" here now
});
var functionX = function() {
var self = this;
var functionY = function(y) {
// If we call "this" in here, we get a reference to functionY,
// but if we call "self" (defined earlier), we get a reference to function X.
}
}
editar: a pesar de que las funciones anidadas dentro de un objeto adoptan el objeto de ventana global en lugar del objeto circundante.