2013-09-27 5 views
5

W kontekście używania metod jako procedur obsługi zdarzeń (tj. $(...).on('something', myObject.handleSomething)). Odkryłem stosunkowo dużą różnicę w wydajności między $ .proxy i _.bind (http://jsperf.com/bind-vs-jquery-proxy/27) i przyjrzałem się ich implementacji.jQuery.proxy vs. underscore.bind

jQuery (http://james.padolsey.com/jquery/#v=1.10.2&fn=proxy) kończy się powrotem:

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

natomiast podkreślenia (http://underscorejs.org/docs/underscore.html#section-60) kończy się na powrocie (konstruktor jest 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; 
}; 

Rozumiem, że _.bind pozwoli mi związać argumenty dla wywołania new, ale czy będzie to miało jakąś praktyczną zaletę, jeśli chcę używać tylko funkcji obsługi zdarzeń jako myObject.handleSomething?

Czy można napisać coś podobnego do _.bindAll przy użyciu $.proxy? Na przykład.

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

Wygląda na to, że masz problemy z kontekstem po otrzymaniu zdarzenia od 'myObject.handleSomething', więc próbujesz powiązać kontekst z obsługą, czy mam rację? jeśli tak, to dlaczego nie przekazać kontekstu jako części danych o wydarzeniu? –

+0

Może cię nie rozumiem, ale to nie ma sensu (w jaki sposób chciałbym uzyskać kontekst "myObject" w danych zdarzeń?). To, czego potrzebuję, to 'Object.bind()', ale z powodu IE muszę użyć biblioteki. Istnieje dość duża różnica w wydajności między plikami underscore.js i jQuery, w których jQuery jest znacznie szybszy. Pierwsza część mojego pytania brzmi, czy ta różnica prędkości wynika z braku ogólności, a druga część mojego pytania dotyczy tego, czy '_.bindAll()' można bezpośrednio implementować z 'jQuery.proxy()'? – thebjorn

Odpowiedz

5

Czy jesteś pewien, że mierzysz wydajność, na której Ci zależy?

Wydaje sprawa Test mierzy wydajność wiązania funkcji, natomiast w tym przypadku badanie mierzy wydajność związany funkcję: http://jsperf.com/bind-vs-jquery-proxy/38

powinieneś być wiążące tylko funkcje skończony (i stosunkowo mała) ilość razy, więc wydajność nie miałaby większego znaczenia. Było to dla mnie zaskoczeniem, ale pomiar wydajności związanej funkcji wydaje się odwracać wyniki.

Należy również pamiętać, że oryginalne wyniki testów były różne w różnych przeglądarkach.

+2

Dobry połów. (Benchmark nie był mój, ale znalazłem linki do niego podczas badania implementacji bindów). Przeprowadziłem test porównawczy z kolekcją przeglądarek, które mam dostępne, i dodałem wersję 39, w której dodałem także bindowanie natywne. – thebjorn

+0

Niezły dodatek. Dzięki! Nie wiedziałem, że istnieje natywna oprawa. – colllin

+0

Dzięki za uderzenie do 1k! :) – colllin