나는 이것이 꽤 오래된 질문이라는 것을 알고 있지만 최근에 이것을 다루었습니다. 이 솔루션에 대해 어떻게 생각하는지 알려주세요.
인수를 강력하게 입력하고 선택 사항으로 사용할 수있는 유틸리티를 만들었습니다. 기본적으로 함수를 프록시로 래핑합니다. 인수를 건너 뛰면 undefined 입니다. 동일한 유형의 옵션 인수가 서로 옆에 여러 개있는 경우 기발 할 수 있습니다 . (사용자 지정 인수 검사를 수행하고 각 매개 변수의 기본값을 지정하기 위해 유형 대신 함수를 전달하는 옵션이 있습니다.)
구현은 다음과 같습니다.
function displayOverlay(/*message, timeout, callback*/) {
return arrangeArgs(arguments, String, Number, Function,
function(message, timeout, callback) {
/* ... your code ... */
});
};
명확성을 위해 다음은 진행중인 작업입니다.
function displayOverlay(/*message, timeout, callback*/) {
//arrangeArgs is the proxy
return arrangeArgs(
//first pass in the original arguments
arguments,
//then pass in the type for each argument
String, Number, Function,
//lastly, pass in your function and the proxy will do the rest!
function(message, timeout, callback) {
//debug output of each argument to verify it's working
console.log("message", message, "timeout", timeout, "callback", callback);
/* ... your code ... */
}
);
};
내 GitHub 리포지토리에서 adjustArgs 프록시 코드를 볼 수 있습니다.
https://github.com/joelvh/Sysmo.js/blob/master/sysmo.js
다음은 리포지토리에서 일부 주석이 복사 된 유틸리티 기능입니다.
/*
****** Overview ******
*
* Strongly type a function's arguments to allow for any arguments to be optional.
*
* Other resources:
* http://ejohn.org/blog/javascript-method-overloading/
*
****** Example implementation ******
*
* //all args are optional... will display overlay with default settings
* var displayOverlay = function() {
* return Sysmo.optionalArgs(arguments,
* String, [Number, false, 0], Function,
* function(message, timeout, callback) {
* var overlay = new Overlay(message);
* overlay.timeout = timeout;
* overlay.display({onDisplayed: callback});
* });
* }
*
****** Example function call ******
*
* //the window.alert() function is the callback, message and timeout are not defined.
* displayOverlay(alert);
*
* //displays the overlay after 500 miliseconds, then alerts... message is not defined.
* displayOverlay(500, alert);
*
****** Setup ******
*
* arguments = the original arguments to the function defined in your javascript API.
* config = describe the argument type
* - Class - specify the type (e.g. String, Number, Function, Array)
* - [Class/function, boolean, default] - pass an array where the first value is a class or a function...
* The "boolean" indicates if the first value should be treated as a function.
* The "default" is an optional default value to use instead of undefined.
*
*/
arrangeArgs: function (/* arguments, config1 [, config2] , callback */) {
//config format: [String, false, ''], [Number, false, 0], [Function, false, function(){}]
//config doesn't need a default value.
//config can also be classes instead of an array if not required and no default value.
var configs = Sysmo.makeArray(arguments),
values = Sysmo.makeArray(configs.shift()),
callback = configs.pop(),
args = [],
done = function() {
//add the proper number of arguments before adding remaining values
if (!args.length) {
args = Array(configs.length);
}
//fire callback with args and remaining values concatenated
return callback.apply(null, args.concat(values));
};
//if there are not values to process, just fire callback
if (!values.length) {
return done();
}
//loop through configs to create more easily readable objects
for (var i = 0; i < configs.length; i++) {
var config = configs[i];
//make sure there's a value
if (values.length) {
//type or validator function
var fn = config[0] || config,
//if config[1] is true, use fn as validator,
//otherwise create a validator from a closure to preserve fn for later use
validate = (config[1]) ? fn : function(value) {
return value.constructor === fn;
};
//see if arg value matches config
if (validate(values[0])) {
args.push(values.shift());
continue;
}
}
//add a default value if there is no value in the original args
//or if the type didn't match
args.push(config[2]);
}
return done();
}