quantum - ¿Por qué no funciona el aliasing de JavaScript?
firebug lite for google chrome (5)
Tengo algunas llamadas a la función de la consola Firebug que quería desactivar cuando Firebug no estaba habilitado, por ejemplo, la consola no está definida. Esto funciona bien en IE6 y FF3, pero no en Chrome:
var log;
if(console){
log = console.log;
}else{
log = function(){ return; }
}
Obtengo un "error de tipo no capturado: invocación ilegal" en Chrome = /
Leí sobre el tema here , donde tienes que aplicar un contexto, que es algo nuevo para mí ... y parece que no puedo encontrar la forma de lograr lo anterior en todos los navegadores ...
El problema con el ajuste de una función (como console.log) en una función es que pierde su contexto, es decir, no mostrará el número de línea correcto del archivo en el que hemos colocado el acceso directo de "registro".
En cambio sugiero algo como esto:
window.log = ((window.console && window.console.log) ?
console.log.bind(console) :
function(){});
Esto funciona con las herramientas de desarrollo de firebug & chrome y no genera errores cuando no hay una consola disponible. Y, lo más importante, muestra el archivo y el número de línea correctos.
Esta solución modifica la respuesta anterior y excelente de para trabajar con IE8. Tendrá que abrir la consola IE8 (presione F12) antes de ejecutar esto. (Si olvida, deberá salir de IE8 por completo y comenzar de nuevo porque incluso si la consola existe, IE8 no creará posteriormente el objeto de la consola ).
Tenga en cuenta que no configuramos el contexto, que era el problema original pero, como resultado, IE8 no requiere ese contexto. (Lo bueno, porque IE8 tampoco proporciona el método de aplicación en el objeto console.log ).
Este código funciona con las últimas versiones de Chrome, FireFox y MSIE. (Es compatible con MSIE6 y no produce un error).
if((typeof console !== "undefined") && ((typeof console.log) !== "undefined"))
{
if ((typeof console.log.apply !== "undefined"))
{
log = function() { console.log.apply(console,arguments) };
}
else
{
log = console.log;
}
}
else
{
log = function() {};
// alert("No debug console");
}
Esto no funciona:
log("hi");
Mientras esto hace:
log.call(console, "hi");
Es obvio que necesita llamar a la función de alias con el contexto correcto, como usted mismo ha mencionado.
Creo que tendrás que usar un envoltorio de función (un cierre que tiene una referencia al contexto original) en lugar de un alias ...
Actualizar
También tenga en cuenta que si verifica la console
directamente, puede obtener un error en tiempo de ejecución cuando la variable no existe. Es mejor que lo compruebes explícitamente como window.console
. Aquí hay una forma de implementar un contenedor de log
condicional:
var log = (function (console) {
return console
? function () { console.log.apply(console, arguments); }
: function () {}
})(window.console);
Sí, debe persistir el contexto:
var log;
if (window.console && typeof console.log === "function"){
// use apply to preserve context and invocations with multiple arguments
log = function () { console.log.apply(console, arguments); };
} else {
log = function(){ return; }
}
Lo que sucede es que el contexto (el valor de this
), se establece implícitamente cuando llama a una función, por ejemplo:
var obj = {
method: function () { return this; }
};
obj.method() === obj; // true
En este caso, está llamando a una función que se define como una propiedad de un objeto, cuando se invoca la función, this
valor se establece en ese objeto.
Ahora como en su ejemplo, si copia una referencia de ese método a una variable:
var method = obj.method;
method() === window; // global object
Como puede ver, this
valor se refiere al objeto global.
Por lo tanto, para evitar este comportamiento implícito, puede establecer el contexto explícitamente, con las funciones de call
o apply
.
hice esto
var log;
log = function() {
if ((window.console != null) && (window.console.log.apply != null)) {
return console.log.apply(console, arguments);
} else {
return function() {};
}
};