新手问题。考虑
var foo = function(func) {
console.log(func.arguments);
}
“foo”函数接受一个参数,这是一个函数。如何在运行时访问与“func”函数一起传递的参数?
编辑:我不想动态地将参数设置为func,我想找出用func传递的参数,以便我可以用它们做其他事情。基本上我想将传入func的参数作为键存储,并将该func的结果存储为值并将它们存储在哈希对象中......最终目标是记住运行“func”的各种结果,具体取决于什么参数传入。现在虽然我的好奇心被激发了如何访问/存储这些论点。
答案 0 :(得分:2)
您无法在foo
的运行时访问它们,因为foo
从未调用过func
{。}}。
foo(function(){
console.log('This is never executed');
});
如果你在func
内执行foo
,那么你当时必须有权访问这些参数:
var foo = function(func) {
func(1, 2, 3); // Now func is called, and you know what the arguments are
}
答案 1 :(得分:0)
如果要传递一个函数作为参数,则该函数没有传入任何参数。您正在传递对函数的引用,该函数必须在函数内部调用,然后您将拥有参数。
您几乎可以说func
的参数是undefined
,因为您尚未调用该函数。从foo
的范围,你可以将参数设置为你想要的。
答案 2 :(得分:0)
你想要这样的东西吗?
var foo = function(func) {
return func.args;
},
bar = function(){
bar.args = arguments;
};
bar('a','b');
foo(bar); // Arguments object ['a','b']
答案 3 :(得分:0)
//
// var
// base_fn = function(){},
// tracer_fn = tracer( base_fn );
//
function tracer( fn ) {
return ( function( argsCache, F, _s ){
// define new fn that will have that capability
// it's a wrapper for original fn
var
fn2 = function(/*...params*/) {
var
// temporary stores original fn's result
out,
// capture passed arguments
theArgs = _s.call( arguments ),
//
// you can implement 'memo' functionality here
// if that's your goal,
// by 'scaning' already processed inputs
// in argsCache array
// and optionaly runing original fn,
// if no match is found
//
// save input and output of fn as h-map
argsIO = {
input : theArgs,
output : null
};
// execute original fn
// pass it captured arguments
// 'remember' it's result
out = F.apply( this, theArgs );
// save calculated value
argsIO.output = out;
// 'push' fn input-output record on the cache
argsCache.push( argsIO );
// return whatever original fn returned
return out;
};
// provide 'static' access to 'closured' cache
// use the array to inspect 'arguments history'
fn2.args = argsCache;
// provide a way to empty cache
fn2.clear = function () {
fn2.args.splice( 0, fn2.args.length );
return fn2.args;
};
// return fn 'upgrade'
return fn2;
} )( [], fn, Array.prototype.slice );
}
function basefn() {
// doStuff( arguments );
// returning value, as well as arguments,
// are recorded by tracer fn
return arguments.length;
}
// get the 'tracer' fn
var
fn = tracer( basefn );
// run it couple of times
// passing arbitrary arguments
fn( 12345, new XMLHttpRequest() );
fn('a', 'z', /^[a-z]+$/ );
fn( {}, [1,2,3] );
fn( location, document );
fn( Math );
//
// access 'args history' through fn.args ( array ) property
//
// var
// lastCallIO = fn.args[ fn.args.length - 1 ];
//
console.log( fn.args );
//
// empty cache, free some memory
//
// fn.clear();
//
//
答案 4 :(得分:0)
调用func时无法访问func的参数,但是可以返回一个包含func的新函数,并在调用该函数时执行任何其他处理。 foo中的局部变量在返回的函数的所有调用之间共享,因此可用于实现memoization。
var foo = function(func) {
return function() {
// Get arguments from func.
console.log("Calling func", arguments);
// Call func with arguments.
return func.apply(null, arguments);
};
};
var bar = function(x) {
return x * 2;
};
var foobar = foo(bar);
console.log(foobar(10));
console.log(foo(bar)(20));
答案 5 :(得分:0)
//
// Function.memo
//
;
( function ( _host_ ) {
var
t = !0,
f = !t,
pn = String( this ),
mmfn = function ( fn, mem_read_callback, mem_write_callback ) {
return ( function( input, output, mrcb, mwcb, k, v ) {
// capture original fns
var
origFn = this,
// define 'memo' fn
mmfn = function ( /*...params*/ ) {
// capture passed arguments
var inputArgs = slc( arguments );
// reset the flag,
// -1 indicates that passed arguments haven't been proccessed yet.
k = -1;
// see if args have been already processed
// scan inputs[]
each( input, function ( input_args, pos ) {
// update k to point to memoized args
return ( is_same_arrays( inputArgs, input_args ) ) ? ( k = pos, f ) : t;
} );
// if k is -1 passed args are processe for the 1st time
// execute original fn,
// store result in output[],
// store arguments[] in inputs[],
// call provided ( optional ) 'mem_write_callback',
// return result
// else
// call provided ( optional )'mem_read_callback',
// return memoized result
return ( k == -1 ) ?
(
v = origFn.apply( this, inputArgs ),
input.push( inputArgs ),
output.push( v ),
( isfn( mwcb ) && mwcb.call( this, inputArgs, v ) ),
v
):
( isfn( mrcb ) && mrcb.call( this, inputArgs, output[k] ), output[k] );
};
// optionaly provide access to cache
mmfn.cache = {
inputs : input,
outputs : output
};
mmfn.mclear = function () {
input.splice( 0, input.length );
output.splice( 0, output.length );
};
// return memoizer
return mmfn;
} ).call( fn, [], [], mem_read_callback, mem_write_callback );
};
// #helpers
function is_same_arrays( a1, a2 ) {
var flg = t;
return ( each( a1, function ( v, k ) { return ( v === a2[k] ) ? t: ( flg = f ) ; } ), flg );
}
function each( arr, fn ) {
for ( var l = arr.length, i = 0; i < l; i++ )
if ( ( fn.call( arr, arr[i], i ) ) === f ) break;
return arr;
}
function slc( args, i, j ) {
return Array.prototype.slice.call( args, i, j );
}
function isfn( fn ) {
return typeof fn === 'function';
}
// attach 'memo' fn to host obj
_host_[pn] = mmfn;
} ).call( new String('memo'), ( typeof context === 'undefined' ? Function : context ) );
var
f1 = Function.memo(
function ( v ) { return v*v; },
function ( inpArr, res ) { console.log('cache read: ', inpArr.join(''),', ', res); },
function ( inpArr, res ) { console.log('cache write: ', inpArr.join(''),', ', res); }
);
f1(1);
f1(2);
f1(1);
f1(2);
f1(1);
f1(3);
//
// logs
//
// cache write, 1 , 1
// cache write, 2 , 4
// cache read, 1 , 1
// cache read, 2 , 4
// cache read, 1 , 1
// cache write, 3 , 9
//