2012-05-24 22 views
50

Por ejemplo, si hago esto:¿Por qué ciertas llamadas a funciones se denominan "invocaciones ilegales" en JavaScript?

var q = document.querySelectorAll; 

q('body'); 

consigo un error "invocación ilegal" en Chrome. No puedo pensar en ninguna razón por la cual esto sea necesario. Por un lado, no es el caso con todas las funciones de código nativo. De hecho, puedo hacer esto:

var o = Object; // which is a native code function 

var x = new o(); 

Y todo funciona bien. En particular, he descubierto este problema cuando se trata de documentos y consolas. ¿Alguna idea?

+0

posible duplicado de [¿Por qué no se puede establecer un alias para document.getElementById()?] (Http://stackoverflow.com/questions/10723496/why-cant-one-set-an-alias-to- document-getelementbyid) – Quentin

+1

posible duplicado de [alias de función de JavaScript no parece funcionar] (http://stackoverflow.com/questions/1007340/javascript-function-aliasing-doesnt-seem-to-work) – HoLyVieR

+0

Duplicado exacto de ["TypeError no capturado: invocación ilegal" en Chrome] (http://stackoverflow.com/questions/9677985/uncaught-typeerror-illegal-invocation-in-chrome) –

Respuesta

86

Es porque ha perdido el "contexto" de la función.

cuando llame:

document.querySelectorAll() 

el contexto de la función es document, y será accesible como this por la aplicación de dicho método.

Cuando acaba de llamar al q, ya no existe un contexto; en su lugar, es el objeto "global" window.

La implementación de querySelectorAll intenta usar this pero ya no es un elemento DOM, es un objeto Window. La implementación intenta llamar a algún método de un elemento DOM que no exista en un objeto Window y el intérprete llama desagradablemente.

Para resolver esto, utilice .bind en nuevas versiones de Javascript:

var q = document.querySelectorAll.bind(document); 

que garantizará que todas las invocaciones posteriores de q tienen el contexto adecuado. Si usted no ha conseguido .bind, utilice esto:

function q() { 
    return document.querySelectorAll.apply(document, arguments); 
} 
+2

Oh, buena llamada. Tienes razón porque puedo hacer: q.apply (document, ['body']); y funciona. – user1152187

+0

Tenga en cuenta que esto no necesariamente funciona para las funciones integradas en IE. Por ejemplo, console.log no tiene un método de aplicación allí. – hugomg

+0

@missingno está bien en Chrome - otro IE "especial", supongo - suspiro ... – Alnitak

-1

En mi caso invocación ilegal se produjo debido al paso variable no declarada para funcionar como argumento. Asegúrese de declarar la variable antes de pasar a la función.

0

Puede suceder por muchas razones, una de las razones más comunes es que está llamando a algo que es a la vez variable y función.

<body> 
<input type="button" value="-" onclick="changeTime(this)"> 
<script> 
    var changeTime = document.getElementsByClassName("changeTimes"); 
    function changeTime(t){ 
      console.dir(t); 
     } 
</script> 
</body> 

por lo que en este caso no está claro qué "ChangeTime" estamos llamando, la variable o función, por lo tanto, "la invocación ilegal".

Cuestiones relacionadas