setTimeout 里 传递字符串代码报错

js高程 第三版 p203 重点:超时调用的代码都是在全局作用域中执行的,因此函数中this 的值在非严格模 式下指向window 对象,在严格模式下是undefined。

不过这里仅仅解释前半句:

超时调用的代码都是在全局作用域中执行的

看题,在控制台输出下代码:

var site = "global";
function foo() {
    var site = "partial";
    setTimeout('alert(site);', 100);
}
foo();

返回什么?

'global'

这就验证了:超时调用的代码都是在全局作用域中执行的;

时间到了,进程空闲的时候, setTimeout 执行的时候,实际上执行的是类似的代码:

var site = "global";
function foo() {
    var site = "partial";
    //  setTimeout(', 100);
}
foo();
alert(site);

这个时候,自然返回的是 ‘global’;

这个时候,如果全局内没有变量 site ,就会报错,这也是常见的错误之一,试试这个:

var s = "global";
function foo() {
    var site = "partial";
    setTimeout('alert(site);', 100);
}
foo();

Uncaught ReferenceError: site is not defined

原因上面解释过了,如果没有闭包,一般在全局内都是无法访问函数内定义的的局部变量,所以报错很正常,但是这个报错也是可以解决的;

    function foo() {
        var site = "partial";
        setTimeout(function() {
            alert(site);
        }, 100);
    }
    foo();

不要用字符串js代码,用函数,这样就没问题,原因是因为

执行 setTimeout 函数代码时,虽然在全局执行,但是 fn 的变量作用域是在 函数定义时 决定的,而不是函数调用时定义的,在 fn 定义时,可以访问到 site,所以在调用时也可以;

而字符串代码,是在执行时才在全局内搜索变量执行,所以全局内找不到就变量会报错;

而且,传递字符串可能导致性能损失,结合上面的易出错,最好不要在 定时器 里传递字符串用作函数,直接传递一个函数会更快更安全。

原文地址:https://www.cnblogs.com/xianshenglu/p/8320878.html