说我有这个功能:
function doSomething(uno, dos, tres) {
// do something
}
和这个对象:
{
dos: 'foo',
tres: 'bar',
uno: 'baz'
}
doSomething
给定这个映射,我该如何调用?我尝试使用apply
,但似乎apply
必须采用列表而不是对象。
说我有这个功能:
function doSomething(uno, dos, tres) {
// do something
}
和这个对象:
{
dos: 'foo',
tres: 'bar',
uno: 'baz'
}
doSomething
给定这个映射,我该如何调用?我尝试使用apply
,但似乎apply
必须采用列表而不是对象。
.
您可以使用下面给出的方法引用上面给出的对象中的每个属性。
doSomething(obj.uno, obj.dos, obj.tres)
Function.apply
只能用于将类数组对象1应用于函数调用。没有等效于 Python 的“关键字参数扩展”,这必须手动完成:
var opts = {
dos: 'foo',
tres: 'bar',
uno: 'baz'
}
doSomething(opts.uno, opts.dos, opts.tres)
如果我们从一个类似数组的对象开始:
var arr = ['baz', 'foo', 'bar']
doSomething.apply(window, arr)
或者将两者放在一起(以便可以更早地处理参数序列的组合):
var arr = [opts.uno, opts.dos, opts.tres]
doSomething.apply(window, arr)
虽然可能(使用非混淆代码)使用2来提取参数名称,进行一些解析,然后编写一些代码来“应用”一个通用对象(或构造一个然后应用的数组),但这是ECMAScript 规范不直接支持。Function.toString
1类数组对象是具有length
名为 和属性的对象0..length-1
。(旧版本的FF有一个错误,但已经修复了很长时间。)
2规范的措辞(“函数的依赖于实现的表示被返回。这种表示具有 FunctionDeclaration 的语法。”)使我相信符合 ES5 的实现应该产生可用于此目的的输出 - 但是,这可能会因实现而异,我在实践中没有探索过这种用法。
您可以尝试使用:
function doSomething() {
for (var i = 0, l = arguments.length; i<l; i++) {
//dosomething
console.log(arguments[i]);
}
}
obj=['foo', 'bar', 'baz'];
doSomething.apply(null, obj);
Apply 接受数组作为第二个参数,但如果您坚持使用 object,您可以轻松将此对象转换为 Array,然后将其与 apply 一起使用。
function objectToArray(obj) {
var arr = [];
for (field in obj)
arr.push(field);
return arr;
}
你可以这样做:
Function.prototype.applyNamed = function (g, argArr) {
var self = this;
var argNames = self.toString().match(/function\s+\w*\s*\((.*?)\)/)[1].split(/\s*,\s*/);
var applyArgs = [];
for(var i=0; i<argNames.length; i++){
applyArgs.push(argArr[argNames[i]]);
}
self.apply(self, applyArgs);
}
function doSomething(uno, dos, tres) {
console.log('uno = ' + uno);
console.log('dos = ' + dos);
console.log('tres = ' + tres);
}
var namedArgs = {
dos: 'foo',
tres: 'bar',
uno: 'baz'
};
doSomething.applyNamed(this, namedArgs);
应该打印:
uno = baz
dos = foo
tres = bar
好吧,如果你真的想要,你实际上可以使用命名参数调用一个方法,但它需要解析函数的字符串表示。你是否应该使用这种技术是有争议的,但你会这样做:
function doSomething(uno, dos, tres) {
// do something
}
var arguments = {
dos: 'foo',
tres: 'bar',
uno: 'baz'
}
function callFunction(fn, namedArguments) {
var orderedArguments = [];
var parameterRegExp = /\(([\s\w\$,]*)\)/;
parameterRegExp.exec(fn.toString())[1].replace(/\s/g, '').split(',').forEach( function(parameterName) {
orderedArguments.push(namedArguments[parameterName]);
});
return fn.apply(this, orderedArguments);
}
callFunction(doSomething, arguments);