2013-09-27 4 views
5

Nel contesto dell'utilizzo dei metodi come gestori di eventi (ad esempio $(...).on('something', myObject.handleSomething)). Ho scoperto la differenza di prestazioni relativamente grande tra $ .proxy e _.bind (http://jsperf.com/bind-vs-jquery-proxy/27) e ho esaminato la loro implementazione.jQuery.proxy vs. underscore.bind

jQuery (http://james.padolsey.com/jquery/#v=1.10.2&fn=proxy) finisce per tornare:

args = core_slice.call(arguments, 2); 
proxy = function() { 
    return fn.apply(context || this, args.concat(core_slice.call(arguments))); 
}; 

mentre sottolineatura (http://underscorejs.org/docs/underscore.html#section-60) finisce per tornare (ctor è var ctor = function(){};):

args = slice.call(arguments, 2); 
return bound = function() { 
    if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments))); 
    ctor.prototype = func.prototype; 
    var self = new ctor; 
    ctor.prototype = null; 
    var result = func.apply(self, args.concat(slice.call(arguments))); 
    if (Object(result) === result) return result; 
    return self; 
}; 

Capisco che _.bind mi permetterà di legare argomenti per una chiamata new, ma avrà qualche vantaggio pratico se voglio utilizzare solo myObject.handleSomething come gestore di eventi?

È possibile scrivere qualcosa di simile a _.bindAll utilizzando $.proxy? Per esempio.

$.proxyAll = function (obj) { 
    for (var attr in obj) if (obj.hasOwnProperty(attr) && $.isFunction(obj[attr])) { 
     obj[attr] = $.proxy(obj[attr], obj); 
    } 
    return obj; 
}; 
+0

Sembra che tu stia avendo problemi di contesto al momento di ottenere il tuo evento gestito da 'myObject.handleSomething', quindi stai cercando di associare il contesto al gestore, ho ragione? in tal caso, perché non passare il contesto come parte dei dati degli eventi? –

+0

Forse ti sto fraintendendo, ma questo non ha nemmeno senso (come potrei anche ottenere il contesto 'myObject' nei dati dell'evento?). Quello di cui ho bisogno è 'Object.bind()', ma a causa di IE ho bisogno di usare una libreria. Esiste una differenza di prestazioni piuttosto ampia tra underscore.js e jQuery, dove jQuery è molto più veloce. La prima parte della mia domanda è se questa differenza di velocità è dovuta alla mancanza di generalità, e la seconda parte della mia domanda è se '_.bindAll()' è direttamente implementabile da 'jQuery.proxy()'? – thebjorn

risposta

5

Sei sicuro di misurare le prestazioni che ti interessano?

Sembra che il tuo banco di prova è misurare la performance di legare la funzione, mentre questo tipo di test misura la performance della funzione legata: http://jsperf.com/bind-vs-jquery-proxy/38

Si dovrebbe essere solo funzioni vincolanti un numero finito (e relativamente piccolo) di volte, quindi le prestazioni non contano davvero. È stata una sorpresa per me, ma misurare le prestazioni della funzione legata sembra capovolgere i risultati.

Inoltre, si noti che i risultati del test originale variavano tra i vari browser.

+2

Buona presa. (Il punto di riferimento non era il mio, ma uno su cui ho trovato dei collegamenti quando si effettuano ricerche sulle implementazioni di bind). Ho eseguito il benchmark con una raccolta di browser che ho a disposizione e ho aggiunto la versione 39 in cui ho aggiunto anche il bind nativo. – thebjorn

+0

Bella aggiunta. Grazie! Non sapevo che esistesse un vincolo nativo. – colllin

+0

Inoltre, grazie per l'urto di 1k! :) – colllin