Ответ 1
Вы можете использовать свойство length
объекта функции для проверки подписи. Пример:
function x(a) {}
function y(a,b) {}
alert(x.length); // shows "1"
alert(y.length); // shows "2"
Скажем, у вас есть две функции со следующими сигнатурами:
addClass( class )
addClass( class, duration )
Они живут в сторонней библиотеке (нет призов для угадывания, которые!!).
Если вы вызываете addClass()
с двумя параметрами, но регистрируете только 1 подпись, не будет ошибки, и будет вызываться подпись 1. Второй параметр игнорируется.
Итак, есть способ обнаружить, что подпись 2 с двумя параметрами была зарегистрирована?
Вы можете использовать свойство length
объекта функции для проверки подписи. Пример:
function x(a) {}
function y(a,b) {}
alert(x.length); // shows "1"
alert(y.length); // shows "2"
В JavaScript нет встроенной перегрузки методов. Вы можете создать свой собственный: http://ejohn.org/blog/javascript-method-overloading/
(Обновление 11/5/15: ссылка кажется мертвой, здесь версия Google Cache)
Итак, если вы делаете
function addClass( class ) { console.log('1 arg'); };
function addClass( class, duration ) { console.log('2 args'); };
второй перезаписывает первый. Поэтому, даже если вы назовете "addClass (1)", вывод будет по-прежнему "2 аргумента". То же, что и при выполнении
someObject.addClass = function(a) {...}
someObject.addClass = function(a, b) {...}
Первая "версия" будет потеряна.
Этого не очень сложно достичь, но метод Resig не очень много, поскольку он проверяет только длину аргументов, которая касается только тангенциально связанных с реальными сигнатурными сигнатурами.
Метод Йоханнеса на самом деле метод, переопределяющий не множественные сигнатуры вызова, и в любом случае не будет работать в режиме JS Strict, где запрещается объявлять несколько функций с тем же именем.
Для правильной реализации вам необходимо реализовать его с помощью переадресации вызовов, заверяя каждую сигнатуру вызова в проверку типа/существования:
function myFunction(arg1, arg2, arg3){
switch(true){
case arg1 instanceof someObject:
myFunction_signature1.apply(this, arguments);
break;
case typeof arg1 === "string":
myFunction_signature2.apply(this, arguments);
break;
}
}
Он становится немного более сложным, когда некоторые параметры также являются необязательными.
Если вы используете node, вы можете использовать func.toString()
и проанализировать результат, чтобы получить подпись, которая была использована.