Ben underscorejs itibaren, bu düşündüğünü oldum:underscorejs'deki optimizasyon nasıl çalışır?
var optimizeCb = function(func, context, argCount) {
if (context === void 0) return func;
switch (argCount == null ? 3 : argCount) {
case 1: return function(value) {
return func.call(context, value);
};
case 2: return function(value, other) {
return func.call(context, value, other);
};
case 3: return function(value, index, collection) {
return func.call(context, value, index, collection);
};
case 4: return function(accumulator, value, index, collection) {
return func.call(context, accumulator, value, index, collection);
};
}
return function() {
return func.apply(context, arguments);
};
};
Yani, görünüşe göre bu optimizasyon sadece (burada context
denir) this
değerini ayarlar geri arama için de geçerlidir. Bu farklı, geri arama için doğrudan call
'u nasıl arayabilir? Bu, performansı nasıl geliştirebilir?
Optimizasyon yalnızca eski JS motorları için geçerliyse sorun değil. Sadece bilmek için ölüyorum.
Düzenleme
muhtemelen söz konusu belli değildi. Demek istediğim bu. optimizeCb kullanıldığı Bir örnek verelim:
_.each = _.forEach = function(obj, iteratee, context) {
iteratee = optimizeCb(iteratee, context); //REMOVE this
var i, length;
if (isArrayLike(obj)) {
for (i = 0, length = obj.length; i < length; i++) {
iteratee(obj[i], i, obj);
//REPLACE with iteratee.call(context, obj[i], i, obj);
}
} else {
var keys = _.keys(obj);
for (i = 0, length = keys.length; i < length; i++) {
iteratee(obj[keys[i]], keys[i], obj);
}
}
return obj;
};
2 yorumları görüntüle: iteratee = optimizeCb(iteratee, context); //REMOVE this
ve iteratee(obj[i], i, obj); //REPLACE with iteratee.call(context, obj[i], i, obj);
. Tartışmaların yavaş olduğunu ve başvuruda yavaş olduğunu anlıyorum. Ama benve vs argümanları çağrıları nasıl görüyorsunuz? 2 yaklaşım arasında fark görmüyorum.
Anahtar sorun, geri arama belirli bir alt çizgi yöntemine geçirilirse, imzanın zaten bilindiğini düşünüyorum. Örneğin, geri arama _.each
'a geçirildiğinde function(value, index, collection)
olmalıdır. Bu gözlem, optimizCb'nin çağrıldığı şekilde onaylanır: optimizeCb'nin arayanı argCount parametresini sağlayabilirse (boş bırakın, 3 demektir), hangi imzanın olduğunu bilir.
Birisi daha ayrıntılı olabilir mi? Çok teşekkürler!
'call', https://jsperf.com/call-apply-segu adresinden çok daha hızlıdır. Düşünüyorum çünkü argüman dizisine erişmek zorunda değil. –
@Moogs: Bağlandığınız test elmaları-elmaları karşılaştırmıyor; Sanırım bunu yapıyor: http://jsperf.com/call-apply-segu/53 Yine de 'apply' üzerinden 'call' için hala belli bir avantaj var. –