简体   繁体   中英

“callback is not the function” and function.apply()

Why this simply doesn't work?

It says typeof(callback) = undefined.

function A(a,callback)
{
document.write(typeof(callback));  
callback();  
return a;  
}

function Run(func,args)
{

   return  func.apply(this||window, args || [
    function () { document.write("blah")}
  ]);

}


Run(A,[1]);

However, without using function.apply it works properly:

function Run2(func,arg)
{

   return  func(arg,
    function () { document.write("blah")}
  );

}

Run2(A,1);

Please be patient I'm new to JS.

The issue is actually occuring in the A function with the callback variable. If you had written the A function as below you will not receive this error:

function A(a, callback) {
    var type = typeof callback;
    document.write(type);
    if(type == "function") callback();//ensure callback is a function
    return a;
}

The first argument of apply is the scope, while the second is an array of arguments. It appears you have this, but args with Run(A,[1]); is only a single argument (1) which will be aligned with the a parameter, however you're missing the function. On the other hand, if args is not set, you're opting to create an array with a single argument of [ function ()... ] , which will again will be aligned with a .

From the looks of it, you're attempting to merge/concatenate the two arrays, when in fact || is used as a comparison operator, or rather an or assignment.

Try this:

func.apply(this||window,args.concat([function () { document.write("blah")}]));

or

args.push(function () { document.write("blah")});
func.apply(this||window,args);

apply() takes the first argument and uses it as this in the function call, and uses the second argument as the arguments to that call. So Run2 is calling A like this (where <func> is your anonymous function):

A(1, <func>);

Run is only passing the one argument in your argument array, 1 and calling it like this:

A(1)

What you want to do is replace your Run with this (I think):

function Run(func,args)
{
    args.push(function () { document.write("blah")});
    // args is now [1, function(){...}]
    return func.apply(this||window, args);
}

You would need an Array length of 2 for your Run() function to work using A() , because it takes two arguments. You just have 1 in args, as [1] . You want [1, func] , so the following would be your solution:

// the keyword this always exists
function Run(func, args){
  args.push(func);
  return  func.apply(this, args || [function(){document.write("blah")}]);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM