javascript中setTimeout调用function时,传递参数的问题

在javascript中调用setTimeout的时候,如果我们是无参数的方法,调用相对简单,直接像下面这样调用就可以了

function fun(){
    // do something here.
}

// 第一个方法
setTimeout(function(){...}, 100);

// 第二个方法
setTimeout(fun, 100);

// 第三个方法
setTimeout("fun()", 100);

在有参数的时候,如果仅仅是字符串类型,也还好解决,第三种方法为我们提供了依据,可以像下面这样:

function fun1(p){
    // do something here;
}

// 注意这里有两个方法
// No.1:将参数写死,直接调用
setTimeout("fun1('parameters')", 100);

//No. 2: 在程序中如果要动态的调用,则可以使用组合参数的形式
setTimeout("fun1('" + paramenter + "')", 100);
//注意,这里需要单引号。

不过事情并非总是如此顺利,我们有的时候需要传递的是对象(这个需求越来越普遍了)。如果是按照这种传参的方式,结果将不可能是我们想要的。而直接像下面这样使用,你应该会发现,是行不通的:

function fun2(objectP){
    // do something here;
}

// 注意,这样是会报错的
// setTimeout(fun2(obj), 100);
// 在Chrome下面得到的错误是:Uncaught SyntaxError: Unexpected identifier,但是有的时候能运行
//这中情况对于在Chrome下的调试是非常的隐晦的。 // BTW:你可以试试在IE下面的报错是怎么样的~

 为了能够顺利调用,我们要做一些工作,最简单直接的就是重写setTimeout了,霸王硬上弓:

function fun2(objectP){
    // do something here;
}

var $st = window.setTimeout;
// 这里覆盖了setTimeout方法,如果需要原始方法的时候,可以使用$st
window.setTimeout = function(funRef, delayTime) {
    if (typeof funRef === 'function') {
        var args = Array.prototype.slice.call(arguments,2);
        var f = function(){ funRef.apply(null, args); }; // 返回无参数方法
        return $st(f, delayTime);//调用无参数方法
    }
    return $st(funRef,delayTime);
}

 在代码中我们能看到,为了后继可以使用原生的setTimeout,我们不得不将setTimeout放入到变量中,这样就可以在有必要的时候调用了。这个方法最大的问题是对原生的setTimeout进行了覆盖,如果代码中原有调用了setTimeout,可能就会出现不必要的麻烦了。为此我们需要一种更简单,并且能够更加容易维护的方法。

分析这个方法,最根本就是让setTimeout调用个无参数的方法,因此,我们可以这样:

// 对方法进行改进
function fun2(objectP){
    return function(){
        // do something here;
        // do(objectP);
    }
}

// 调用
setTimeout(fun2(p), 100);

 这样,就可以直接在setTimeout中调用了。这样就不会和现有的代码产生冲突,并且,在维护的时候,也能更加的方便。 

Saturday, November 03, 2012 | Javascript(s)

文章评论

  • # re: javascript中setTimeout调用function时,传递参数的问题
    • devi
    • 9/19/2015 4:06 PM
    第二段代码内容中的当函数参数为字符串时,(第10行),为什么要含有单引号呢,那个是什么意思.
  • # re: javascript中setTimeout调用function时,传递参数的问题
    @devi:
    var p="a test message";
    var para="p";
    function func1(p){
        alert(p);
    }
    
    setTimeout("func1('p')", 100);
    setTimeout("func1(p)", 100);
    
    // 想想区别
    setTimeout("func1('" + para + "')", 100);
    setTimeout("func1(" + para + ")", 100);
    
    

    上面的代码,就是有引号没引号的区别了。
    没有引号,p这个参数将会去当前作用域中找,有这个p对象,将会直接使用对象。

     关键点:会先计算参数表达式的值!

  • # re: javascript中setTimeout调用function时,传递参数的问题
    • xxy
    • 4/18/2016 5:19 PM
    第一个方法,我自己调试了下,好像没有延迟作用诶?
  • # re: javascript中setTimeout调用function时,传递参数的问题
    @xxy: 是的,是我的失误,应该是将func定义直接放进去,已经调整。原来的代码会导致先计算结果。

发表评论

Please add 4 and 4 and type the answer here:

关于博主

  一枚成分复杂的网络IT分子,属于互联网行业分类中的杂牌军。