Skip to content

Instantly share code, notes, and snippets.

@theshock
Created August 4, 2011 14:01
Show Gist options
  • Save theshock/1125213 to your computer and use it in GitHub Desktop.
Save theshock/1125213 to your computer and use it in GitHub Desktop.
Idea: JavaScript optimization using callback.length
// Идея в том, чтобы парсить колбеки на количество аргументов в заголовке и за счёт этого избежать ненужных вычислений.
/***************************************************************/
// Реализация приблизительно такая:
function afterCount (callback) {
var a = callback.length > 0 ? hardACount() : null;
var b = callback.length > 1 ? hardBCount() : null;
var c = callback.length > 2 ? hardCCount() : null;
callback(a,b,c);
}
afterCount(function (a) {
// вызывается только hardACount
});
afterCount(function (a, b) {
// вызывается только hardACount и hardBCount
});
afterCount(function (a, b, c) {
// вызывается hardACount, hardBCount и hardCCount
});
/***************************************************************/
// Где это может пригодиться:
ajax.get(url, function (response) {
// do smth
});
// vs
ajax.get(url, function () {
// Для этой функции мы можем не разбирать ответ в формате json или xml
// внутри ajax.get, ведь он не используется. Сама ajax.get увеличится
// на одну строчку, но уменьшатся количество вычислений
});
/***************************************************************/
// Асинхронное получение данных пользователя:
function asyncGetUserData (fn) {
getFromCache( 'name', function (name) {
if (fn.length == 1) return fn(name);
getFromDb( 'user', name, function () {
fn(name, profile);
});
});
};
// пример использования:
asyncGetUserData(function (name, profile) {/* code */});
asyncGetUserData(function (name ) {/* code */});
// Обращение к базе произойдёт, только если у колбека два аргумента
// Иначе - пустая трата времени и ресурсов
/***************************************************************/
// Недостаток - неожиданное для пользователя API поведение arguments.
// Пока это только идея. Вдруг кому-то пригодится.
@azproduction
Copy link

Можно сделать небольшой апгрейд, вот идея:

var value = [1, 2];

value.__defineGetter__(2, function () {
    console.log('__defineGetter__ Trigger!');
    return 3;
});

function B(a, b) {
   console.log('B', arguments, arguments.length === B.length); 
}

function C(a, b, c) {
   console.log('C', arguments, arguments.length === C.length);
}

B.apply(this, value.slice(0, B.length)); // B [1, 2] true

// __defineGetter__ Trigger!
C.apply(this, value.slice(0, C.length)); // C [1, 2, 3] true

Вобщем нужно что-то, чтобы избавиться от

var a = callback.length > 0 ? hardACount() : null;
var b = callback.length > 1 ? hardBCount() : null;
var c = callback.length > 2 ? hardCCount() : null;

Для извращенцев, использующих arguments у меня есть извращенная идея :D

// v0.0.1a
function isCallbackUsingArguments(callback) {
    return /arguments/.test(callback);
}

isCallbackUsingArguments(function () {
    return arguments[0];
}) // true

isCallbackUsingArguments(function (a) {
    return a;
}) // false

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment