Domanda

Ho fatto molte ricerche in merito, ma sembra che i metodi utilizzati siano incoerenti e vari.

Ecco alcuni metodi che ho usato in passato:

/* 1: */  typeof myFunc === 'function'
/* 2: */  myFunc.constructor === Function
/* 3: */  myFunc instanceof Function

Nell'ambito della mia ricerca ho dato un'occhiata a come alcune famose biblioteche lo hanno realizzato:

 /* jQuery 1.2.6: */  !!fn && typeof fn != "string" && !fn.nodeName && fn.constructor != Array && /^[\s[]?function/.test( fn + "" )
 /* jQuery 1.3b1: */  toString.call(obj) === "[object Function]"
/* Prototype 1.6: */  typeof object == "function"
      /* YUI 2.6: */  typeof o === 'function'

Sono stupito che ci siano così tanti metodi diversi che gli esseri umani usano, sicuramente è stato concordato un solo test accettabile? E sono completamente all'oscuro di quali fossero le intenzioni con la versione di jQuery 1.2.6, sembra un po 'OTT ...

Quindi, il mio quesiton rimane, qual è il modo migliore * di testare una funzione?

Gradirei anche alcuni approfondimenti su alcuni dei metodi di cui sopra, in particolare jQuery 1.2.6. (Vedo cosa stanno facendo, sembra strano)

[*] Per "migliore", intendo il metodo compatibile con più browser più accettato.


EDIT: Sì, lo so che è stato discusso in precedenza, ma vorrei ancora qualche discussione sul metodo più efficace. Perché ci sono così tanti diversi metodi usati?

Finora le discussioni su SO hanno citato solo l'operatore typeof (principalmente) ma nessuno ha accennato all'efficacia dei metodi alternativi.

È stato utile?

Soluzione

Il modo migliore per verificare se un oggetto è una funzione è typeof myFunc === 'function' . Se si utilizza una libreria, utilizzare il test di funzione di quella libreria: jQuery.isFunction (myFunc) .

Le cose possono essere erroneamente riportate come funzioni quando si utilizza typeof . Questo è molto raro ma una libreria è lì per rimuovere queste incoerenze. jQuery aggira questi problemi:

  • I rapporti di Firefox funzionano con typeof document.createElement (" object ")
  • I rapporti di Safari funzionano con typeof document.body.childNodes
  • Le versioni precedenti di Firefox riportavano espressioni regolari come funzioni (questo non è il caso della versione 3.0).
  • Alcune funzioni globali integrate di IE ( alert ) e alcuni metodi di nodo ( getAttribute ) sono riportati come di tipo " oggetto " ;.

L'uso di instanceof piuttosto che typeof elude alcuni di questi. Ad esempio, document.createElement (" object ") instanceof Function è false in Firefox.

Puoi visualizzare la nascita del primo metodo nei commenti per il biglietto originale (# 3618) . Il nuovo metodo è tratto da changeset 5947 e sembra essere stato inventato da Resig per risolvere perdite di memoria IE . Probabilmente è più lento, ma più piccolo e più pulito.

Non c'è molta differenza tra == e === qui in termini di come funzionano le cose, ma la valutazione rigorosa è sempre leggermente più veloce e quindi preferita.

Altri suggerimenti

John Resig, lo sviluppatore di jQuery, sembra aver fatto delle scelte bizzarre all'interno di jQuery.

toString.call(obj) === "[object Function]"

sembra abbastanza pulito ma non riesco a pensare a nessuna situazione in cui quanto sopra sarebbe vero in cui il semplice approccio typeof fallirebbe ma forse sa qualcosa che il resto dell'uso non ha.

typeof o === "function"

Vorrei andare con quest'ultimo dal momento che ha una maggiore chiarezza, a meno che tu non abbia una forte prova che non funzionerà.

Perché usare l'uguaglianza rigorosa su typeof poiché entrambi gli operandi sono stringhe? Sto trascurando qualche problema?

Ad ogni modo, vorrei andare nel modo più semplice di digitareof, che sembra fatto per quello ed è leggibile. Anche instanceof è leggibile, ma sembra insistere maggiormente sul fatto che una funzione sia un oggetto, il che potrebbe essere irrilevante per il problema.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top