2010-12-03 5 views
13

Ceci est probablement une question stupide, alors s'il vous plaît restez avec moi.Utilisation de toString() au lieu du constructeur en JavaScript

Pourquoi est-ce que je vois tant d'exemples testant si un objet est une fonction en comparant toString() à "[object Function]"?

Par exemple:

function isFunction(obj) { 
    return Object.prototype.toString.call(obj) == "[object Function]"; 
} 

On ne peut pas utiliser instanceof Function ou obj.constructor === Function? Sont-ils compatibles avec plusieurs navigateurs?

Cette semble inefficace, mais est-ce? Pourquoi?

+0

double possible (http://stackoverflow.com/questions/3514336/jquerys-isfunction-and-internetexplorer) –

Répondre

7

La réponse courte est que typeof /foo/ est une fonction des navigateurs Webkit. CMS a long dessiné explication @jQuery's isFunction and InternetExplorer

Et instanceOf n'est pas fiable, car comme le souligne Zuriy sur:

Les problèmes se posent en matière de scripts dans des environnements DOM multi-images. En un mot, les objets Array créés dans un iframe ne partagent pas les [[Prototype]] avec des tableaux créés dans un autre iframe. Leurs constructeurs sont des objets différents et donc les contrôles instanceof et constructor échouent:

Grand article @http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/ par Zuriy sur le sujet.

Exemple tiré de l'article:

var iframe = document.createElement('iframe'); 
document.body.appendChild(iframe); 
xArray = window.frames[window.frames.length-1].Array; 
var arr = new xArray(1,2,3); // [1,2,3] 

// Boom! 
arr instanceof Array; // false 

// Boom! 
arr.constructor === Array; // false 
+0

quand/pourquoi instanceOf n'est-il pas fiable? – Matt

+0

Je peux voir pourquoi "instanceOf" est mauvais, mais qu'en est-il de l'utilisation de "obj.constructor". Pouvons-nous avoir un exemple? –

+0

@meder merci! Je n'en avais aucune idée. – Matt

1

Ils ne testent pas leur méthode toString, ils appellent la méthode toString du prototype d'objet sur obj pour la convertir en chaîne. Une fonction se transforme en '[fonction objet]' en une chaîne.

instanceof n'est pas fiable et n'est pas non plus le moyen du constructeur. Le constructeur nécessite une vérification pour voir si obj est nul ou pas avant d'essayer d'accéder à sa propriété constructeur - Je suppose aussi que c'est un peu plus lent que la méthode toString.

+0

je peux [isFunction de jQuery et InternetExplorer] voir pourquoi "instanceof" n'est pas fiable (exemple function Array() {}), mais où "constructor" échouerait-il? –

+1

@Eric pour exactement la même raison que "instanceof" étant un problème: la référence "constructeur" serait différente pour les objets de deux trames différentes, même si elles étaient construites par la "même" fonction, car chaque * instance * du La fonction constructeur (dans chaque fenêtre séparée) est distincte. – Pointy

Questions connexes