Javascript 带参数的setTimeout

Javascript 带参数的setTimeout,javascript,Javascript,在试图解决这个问题时有点头疼。我想做的是使用参数自定义setTimeout,而不必创建函数来传递它。让我用代码解释一下: 想要避免: function makeTimeout(serial){ serial.close(); } setTimeout(makeTimeout(sp.name), 250); 我想做的是通过以下方式调用1行程序: setTimeout(function(arg1){ .... }(argument_value), 250); 这是可以完成的,还是只能传入一

在试图解决这个问题时有点头疼。我想做的是使用参数自定义setTimeout,而不必创建函数来传递它。让我用代码解释一下:

想要避免:

function makeTimeout(serial){
  serial.close();
}

setTimeout(makeTimeout(sp.name), 250);
我想做的是通过以下方式调用1行程序:

setTimeout(function(arg1){ .... }(argument_value), 250);

这是可以完成的,还是只能传入一个无参数函数?

可以传入一个匿名函数,该函数使用给定参数调用
makeTimeout

setTimeout(function () {
  makeTimeout(sp.name);
}, 250);
还有一种选择,使用:

但是,此功能是ECMAScript第5版的一项功能,尚未在所有主流浏览器中得到支持。为了兼容性,您可以包括MDN上提供的
bind
,允许您在本机不支持它的浏览器中使用它


如果不想声明单独的函数,可以使用立即调用的函数表达式和闭包,例如

// Parameter to use
var bar = 'bar';

// Function to call
function foo(arg) {
  alert(arg);
}

// Go…
setTimeout(
  (function(arg1){
    return function(){
      foo(arg1);
    };
  }(bar)), 2000);
或者,您可以使用函数构造函数:

setTimeout( Function('foo(bar)'), 2000);
也可以使用字符串:

setTimeout('foo(bar)', 1000);
这基本上是一样的。现在等待“但这就像使用eval,每个人都知道eval是邪恶的,是一个巨大的安全漏洞-你所有的长子都注定了!”


但严重的是,
eval
(和函数构造函数)效率低下,可能会导致延迟编程,因此请使用另一个选项,例如上面的第一个选项。

一些浏览器似乎增加了将参数传递给setTimeout的功能:

语法:
设置超时(函数(p1,p2){},1000,p1,p2)(添加任意数量的参数)

如果您想确保它在任何地方都能工作,可以使用附带的代码

注意:如果要在安装后立即设置超时,最好使用callback参数并在其中执行

例如

installSwizzledTimeout(function(param1,param2){
    setTimeout(myFunc,200,param1,param2);},param1,param2);
}
这是因为它使用一种技巧来检测是否需要它,方法是设置一个非常短的超时并计算参数

window.swizzledSetTimeout = function (fn, ms) {
    if (arguments.length === 2) {
        //console.log("Bypassing swizzledSetTimeout");
        return window.originalSetTimeout(fn, ms);
    } else {
        var args = [];
        for (i = 2; i < arguments.length; i++) {
            args.push(arguments[i])
        };
        //console.log("Setting swizzledSetTimeout for function (",args,") {...} in ",ms," msec");
        var retval = window.originalSetTimeout(function () {
            //console.log("Invoking swizzledSetTimeout for function (",args,") {...}");
            fn.apply(null, args);
        }, ms);
        return retval;
    }
}

function installSwizzledTimeout(cb) {
    var args = [];
    for (i = 1; i < arguments.length; i++) {
        args.push(arguments[i])
    };
    setTimeout(function (arg) {
        //console.log("arguments.length:",arguments.length,window.setTimeout.toString());
        if (arguments.length == 0) {

            function doInstall() {
                //console.log("Installing new setTimeout");
                window.originalSetTimeout = window.setTimeout;
                window.setTimeout = function setTimeout() {
                    return window.swizzledSetTimeout.apply(null, arguments);
                };
                if (cb) {
                    cb.apply(null, args);
                };
            }

            if (window.setTimeout.toString().indexOf("swizzledSetTimeout") < 0) {
                doInstall();
            }
        } else {
            //console.log("existing set time supports arguments ");
            if (cb) {
                cb.apply(null, args);
            };
        }
    }, 0, 1, 2, 3, 4);
}
window.swizzledSetTimeout=函数(fn,ms){
if(arguments.length==2){
//log(“绕过swizzledSetTimeout”);
返回窗口。原始设置超时(fn,毫秒);
}否则{
var args=[];
对于(i=2;i
我有一个方法,它需要一个常数超时设置,并且最终执行的函数也有参数,所以我使用匿名函数做了如下操作:

function checkPageLoaded(checker, callback, nextCallTime) {
    return () => {
        let checkoutLoader = document.querySelector(checker);
        if(checkoutLoader === null)
            callback();
        else
            setTimeout(checkPageLoaded(checker, callback, nextCallTime), nextCallTime);
    }
}
然后就这样称呼它:

setTimeout(checkPageLoaded('.loader', reloadPagination, 500), 500);

这样,使用参数执行的所需函数将被定义为匿名函数。

应注意,调用函数时传递给
makeTimeout
的值将是
sp.name
的值,这可能与调用
setTImeout
时的值不同。根据,bind现在受到主要浏览器的支持。正如RobG所说,要使它100%工作,需要在超时过期时使用闭包,值
sp.name
可能已更改。我不确定为什么该绑定是唯一对我有效的绑定!
setTimeout(checkPageLoaded('.loader', reloadPagination, 500), 500);