javascript - ejemplos - ¿Pasar el contexto "este" correcto a la devolución de llamada setTimeout?
timer jquery ejemplos (5)
En otros navegadores que no sean Internet Explorer, puede pasar parámetros a la función juntos después de la demora:
var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);
Entonces, puedes hacer esto:
var timeoutID = window.setTimeout(function (self) {
console.log(self);
}, 500, this);
Esto es mejor en términos de rendimiento que una búsqueda de ámbito (almacenar en caché en una variable fuera del tiempo de espera / expresión de intervalo) y luego crear un cierre (mediante $.proxy
o Function.prototype.bind
).
El código para que funcione en IEs de Webreflection :
/*@cc_on
(function (modifierFn) {
// you have to invoke it as `window`''s property so, `window.setTimeout`
window.setTimeout = modifierFn(window.setTimeout);
window.setInterval = modifierFn(window.setInterval);
})(function (originalTimerFn) {
return function (callback, timeout){
var args = [].slice.call(arguments, 2);
return originalTimerFn(function () {
callback.apply(this, args)
}, timeout);
}
});
@*/
Esta pregunta ya tiene una respuesta aquí:
¿Cómo paso el contexto en setTimeout
? Quiero llamar a this.tip.destroy()
si this.options.destroyOnHide
después de 1000 ms. ¿Cómo puedo hacer eso?
if (this.options.destroyOnHide) {
setTimeout(function() { this.tip.destroy() }, 1000);
}
Cuando intento lo anterior, this
refiere a la ventana.
Hay métodos abreviados ya preparados (azúcar sintáctica) a la envoltura de función @CMS con la que se responde. (A continuación, suponiendo que el contexto que desea es this.tip
).
ECMAScript 5 ( navegadores actuales , Node.js) y Prototype.js
Si selecciona un navegador compatible con ECMA-262, 5ta edición (ECMAScript 5) o Node.js , podría usar Function.prototype.bind
. Opcionalmente, puede pasar cualquier argumento de función para crear funciones parciales .
fun.bind(thisArg[, arg1[, arg2[, ...]]])
De nuevo, en tu caso, prueba esto:
if (this.options.destroyOnHide) {
setTimeout(this.tip.destroy.bind(this.tip), 1000);
}
La misma funcionalidad también se ha implementado en Prototype (¿otras bibliotecas?).
Function.prototype.bind
puede implementarse de esta manera si desea una compatibilidad personalizada hacia atrás (pero observe las notas).
ECMAScript 2015 ( algunos navegadores , Node.js 5.0.0+)
Para el desarrollo de vanguardia (2015), puede utilizar las funciones de la flecha gruesa , que forman parte de la especificación ECMAScript 2015 (Harmony / ES6 / ES2015) ( examples ).
Una expresión de función de flecha (también conocida como función de flecha gruesa ) tiene una sintaxis más corta en comparación con las expresiones de función y vincula de forma léxica
this
valor [...].
(param1, param2, ...rest) => { statements }
En tu caso, prueba esto:
if (this.options.destroyOnHide) {
setTimeout(() => { this.tip.destroy(); }, 1000);
}
jQuery
Si ya está utilizando jQuery 1.4+, hay una función preparada para configurar explícitamente el contexto de this
función.
jQuery.proxy() : toma una función y devuelve una nueva que siempre tendrá un contexto particular.
$.proxy(function, context[, additionalArguments])
En tu caso, prueba esto:
if (this.options.destroyOnHide) {
setTimeout($.proxy(this.tip.destroy, this.tip), 1000);
}
Underscore.js , lodash
Está disponible en Underscore.js, así como en lodash, como _.bind(...)
1 , 2
1 Enlazar una función a un objeto, lo que significa que siempre que se llame a la función, el valor de
this
será el objeto. Opcionalmente, vincule los argumentos a la función para completarlos previamente, también conocida como aplicación parcial.
_.bind(function, object, [*arguments])
En tu caso, prueba esto:
if (this.options.destroyOnHide) {
setTimeout(_.bind(this.tip.destroy, this.tip), 1000);
}
bind jquery underscore.js ecmascript-5 prototypejs node.js
NOTA: Esto no funcionará en IE
var ob = {
p: "ob.p"
}
var p = "window.p";
setTimeout(function(){
console.log(this.p); // will print "window.p"
},1000);
setTimeout(function(){
console.log(this.p); // will print "ob.p"
}.bind(ob),1000);
Si estás usando el Underscore.js , puedes usar el bind
.
P.ej
if (this.options.destroyOnHide) {
setTimeout(_.bind(this.tip.destroy, this), 1000);
}
setTimeout
guardar una referencia al contexto donde se realiza la setTimeout
función setTimeout
, porque setTimeout
ejecuta la función con this
apuntando al objeto global:
var that = this;
if (this.options.destroyOnHide) {
setTimeout(function(){that.tip.destroy()}, 1000);
}
Puede probar fácilmente que setTimeout
establece this
en el objeto global mediante:
(function () {
alert(this); // alerts hello
setTimeout(function(){
alert(this == window); // true
}, 1000);
}).call("hello");
Ver también: