2010-01-18 3 views
3

Je ne parviens pas à utiliser les fonctions de code natif en tant qu'objets JavaScript dans les navigateurs WebKit. Est-il impossible d'aliaser directement ces fonctions?Utilisation de fonctions de code natif en tant qu'objets JavaScript dans WebKit

Ceci est plus facile à expliquer par exemple, voici donc ce que je suis en cours d'exécution dans la console Outils de développement:

console.warn; 
// Outputs: 
// function warn() { 
//  [native code] 
// } 

console.warn("console.warn"); 
// Outputs: "console.warn" 

var _c = console; 
_c.warn("_c.warn"); 
// Outputs: "_c.warn" 

var _w = console.warn; 
_w("_w"); 
// Outputs: "TypeError: Type error" on Safari/WebKit (Mac) 
// Outputs: "TypeError: Illegal invocation" on Chrome (Mac) 

var _w2 = function() { console.warn.apply(console, arguments); } 
_w2("_w2"); 
// Outputs: "w2" 

Cette question a été soulevée comme je l'ai essayé d'utiliser jQuery Lint dans Safari; il utilise l'approche suivante pour éviter la rupture si window.console n'existe pas:

_console = { 
    warn: window.console && console.warn || function(){}, 
    ... 
} 

_console.warn("some error"); 

Voici mon solution temporaire:

if((jQuery.browser.safari || jQuery.browser.webkit) && window.console) { 
    jQuery.LINT.level = 3; 
    jQuery.LINT.console = { 
     warn: function() { console.warn.apply(console, arguments); }, 
     group: function() { console.group.apply(console, arguments); }, 
     groupEnd: function() { console.groupEnd(); }, 
     groupCollapsed: function() { console.group.apply(console, arguments); }, 
     log: function() { console.log.apply(console, arguments); } 
    } 
} 

Répondre

7

Vous ne pouvez pas alias aucune méthode en JavaScript, natif ou non, WebKit ou non.

Lorsque vous dites var _w = console.warn;, vous supprimez warn de son objet propriétaire console et le traitez comme une fonction autonome. Lorsque vous l'appelez, il ne reçoit aucune référence this au , il ne fonctionne donc pas.

Vous trouverez peut-ce inhabituel de la façon dont les méthodes liées travailler dans d'autres langues, mais c'est à quel point les appels de méthode JavaScript sont conçus: la référence this est passée à une fonction uniquement basée sur ce owner est en owner.method() (ou owner['method']()). Si la fonction est appelée seule sans propriétaire, this est définie sur l'objet window et la méthode tombera très probablement.

Pour contourner ce problème et passer dans un this approprié, vous devez utiliser method.call (ou method.apply) explicitement comme décrit par @slebetman, ou faire votre propre fonction liée à l'aide d'une fermeture comme var _w= function() { console.warn.apply(console, arguments) }; ou, dans ECMAScript Cinquième édition, method.bind(owner) .

+0

Bizarrement, les nouvelles versions de Firebug ne vous dérange pas si vous alias les méthodes 'console'. – James

+0

Eh bien d'accord, j'ai menti un peu. :-) Bien sûr, cela dépend de la mise en œuvre; il est naturellement possible de faire une fonction qui peut être rappelée sans se préoccuper de ce qu'est son «ceci», auquel cas aliaser la méthode dans une variable fonctionnera ... bien que ce ne soit clairement pas quelque chose sur lequel vous pouvez compter. (En outre, pour les 'objets hôtes' non natifs fournis par le navigateur, tous les paris sont désactivés.) – bobince

2

Cela devrait être:

console.warn.apply(console,arguments); 

Le premier paramètre appliquer est la valeur de cette pour passer dans la méthode warn.

+0

Merci; J'ai mis à jour ma question pour corriger cet oubli. Il résout la majorité des problèmes que j'avais, mais je vais attendre un peu plus longtemps pour voir si quelqu'un a de bonnes informations sur les fonctions natives dans WebKit. – PCheese

Questions connexes