优雅做它:
var myFunc = (function (foo, bar, baz) {
// does whatever it is supposed to do
}).
withNamedArguments({foo:"default for foo", bar:"bar", baz:23 });
myFunc({foo:1}); // calls function(1, "bar", 23)
myFunc({}); // calls function("default for foo", "bar", 23);
myFunc({corrupt:1}); // calls function({corrupt:1})
myFunc([2,4], 1); //calls function([2,4], 1)
即使这一个工程
Array.prototype.slice =
Array.prototype.slice.withNamedArguments({start:0, length:undefined});
[1,2,3].slice({length:2}) //returns [1,2]
[1,2,3].slice(1,2) //returns [2,3]
...或者在这里,parseInt函数()
parseInt = parseInt.withNamedArguments({str:undefined, base:10});
parseInt({str:"010"}); //returns 10
只是增强功能对象:
Function.prototype.withNamedArguments = function(argumentList) {
var actualFunction = this;
var idx=[];
var ids=[];
var argCount=0;
// construct index and ids lookup table
for (var identifier in argumentList){
idx[identifier] = argCount;
ids[argCount] = identifier;
argCount++;
}
return function(onlyArg) {
var actualParams=[];
var namedArguments=false;
// determine call mode
if (arguments.length == 1 && onlyArg instanceof Object) {
namedArguments = true;
// assume named arguments at the moment
onlyArg = arguments[0];
for (name in onlyArg)
if (name in argumentList) {
actualParams[idx[name]] = onlyArg[name];
} else {
namedArguments = false;
break;
}
}
if (namedArguments) {
// fill in default values
for (var i = 0; i < argCount; i++) {
if (actualParams[i] === undefined)
actualParams[i] = argumentList[ids[i]];
}
} else
actualParams = arguments;
return actualFunction.apply(this, actualParams);
};
};
这实际上是我在思考我的问题一段时间后得出的结论。 – smack0007 2010-11-12 09:12:21
@ smack0007:这是迄今为止最简单的解决方案。你可以(当然)以相反的方式做到这一点:确保所有东西都可以通过对象访问。不过,这可能会更冗长些。 – jwueller 2010-11-12 09:59:03