请看如下代码:(function(){
var w=this, JS=function(s){//插入JS
var oh=document.getElementsByTagName('head')[0], os=document.createElement('script');
os.setAttribute('type', 'text/javascript');
os.setAttribute('src', s);
oh.appendChild(os)
};
window.setTimeout("JS('js2.js')",5000);//这里怎么延时执行不了啊?说JS未定义。如果是JS('js2.js')就没有问题,这是为什么啊???
})();
var w=this, JS=function(s){//插入JS
var oh=document.getElementsByTagName('head')[0], os=document.createElement('script');
os.setAttribute('type', 'text/javascript');
os.setAttribute('src', s);
oh.appendChild(os)
};
window.setTimeout("JS('js2.js')",5000);//这里怎么延时执行不了啊?说JS未定义。如果是JS('js2.js')就没有问题,这是为什么啊???
})();
所以用"JS('js2.js')"时,显示JS未定义用JS('js2.js')时,是先调用了JS函数,相当于window.setTimeout(undefined, 5000)
window.setTimeout(JS('js2.js'),5000);
那定时器根本就没起作用,JS函数直接执行了。这样会报错的,setTimeout第一个参数要么是个串,要么是个函数句柄。对比两种可行情况
//1
<html>
<head></head>
<body>
<script>
(function(){
var w=this, JS=function(s){//插入JS
var oh=document.getElementsByTagName('head')[0], os=document.createElement('script');
os.setAttribute('type', 'text/javascript');
os.setAttribute('src', s);
oh.appendChild(os)
};
window["JS"] = JS;
window.setTimeout("JS('js2.js')",5000);//这里怎么延时执行不了啊?说JS未定义。如果是JS('js2.js')就没有问题,这是为什么啊???
})();
</script>
</body>
</html>//2
<html>
<head></head>
<body>
<script>
(function(){
var w=this, JS=function(s){//插入JS
return function(){
var oh=document.getElementsByTagName('head')[0], os=document.createElement('script');
os.setAttribute('type', 'text/javascript');
os.setAttribute('src', s);
oh.appendChild(os)
}
};
window.setTimeout(JS('js2.js'),5000);//这里怎么延时执行不了啊?说JS未定义。如果是JS('js2.js')就没有问题,这是为什么啊???
})();
</script>
</body>
</html>
<html>
<head></head>
<body>
<script>
(function(){
var w=this, JS=function(s){//插入JS
return function(){
var oh=document.getElementsByTagName('head')[0], os=document.createElement('script');
os.setAttribute('type', 'text/javascript');
os.setAttribute('src', s);
oh.appendChild(os)
}
};
});
window.setTimeout(JS('js2.js'),5000);//这里怎么延时执行不了啊?说JS未定义。如果是JS('js2.js')就没有问题,这是为什么啊???
</script>
</body>
</html>把延迟代码放到函数体外,重新来调用你的那段代码
<html>
<head></head>
<body>
<script>
(function(){
var w=this, JS=function(s){//插入JS
return function(){
var oh=document.getElementsByTagName('head')[0], os=document.createElement('script');
os.setAttribute('type', 'text/javascript');
os.setAttribute('src', s);
oh.appendChild(os)
}
};
});
window.setTimeout("JS('js2.js')",5000);//这里怎么延时执行不了啊?说JS未定义。如果是JS('js2.js')就没有问题,这是为什么啊???
</script>
</body>
</html>这样我测试是可以的延迟执行的,没问题,你用我上面这段代码测试下
var w=this, window.JS=function(s){//插入JSwindow.setTimeout("window.JS('js2.js')",5000)可见范围问题
当settimeout时候 转换字符串为代码"js()" 这个时候 已经出了上面的匿名函数的范围 已经找不到JS了
<head></head>
<body>
<script>
(function(){
var w=this, JS=function(s){//插入JS
var oh=document.getElementsByTagName('head')[0], os=document.createElement('script');
os.setAttribute('type', 'text/javascript');
os.setAttribute('src', s);
oh.appendChild(os)
};
window["JS"] = JS;
window.setTimeout("JS('js2.js')",5000);//这里怎么延时执行不了啊?说JS未定义。如果是JS('js2.js')就没有问题,这是为什么啊???
})();
</script>
</body>
</html>这样是可以的
(function(){
var w=this, JS=function(s){//插入JS
var oh=document.getElementsByTagName('head')[0], os=document.createElement('script');
os.setAttribute('type', 'text/javascript');
os.setAttribute('src', s);
oh.appendChild(os)
};
window.setTimeout(function(){JS('js2.js');}, 5000);
})();
首先,window.setTimeout()方法,第一个参数可以是字符串,也可以是函数的句柄也就是引用。
如果是函数句柄,那么就直接放入任务等待队列中,如果对该进行了执行(即后面加上了()),setTimeout执行相当于是这个函数的返回值(一般来说也是函数),如:
function sayHello(){
return function(){alert("Hello!")}
}
window.setTimeout(sayHello(),1000);
1s后执行alert("Hello!");因为传参的时候把sayHello方法执行了,所以实际上放入任务执行等待队列中(js是单线程执行的)的是sayHello的返回值:函数function(){alert("Hello!")},等到1s后js引擎取出该方法并执行。
那如果是window.setTimeout(sayHello,1000);会怎么样呢?这个时候放入队列中的就是函数sayHello,1s后会取出该函数,结果就是返回了一个函数即window.setTimeout(sayHello,1000);
如果传入的第一个参数是字符串,那么等待时间结束,实际执行的就类似于eval("....")这样的代码,而这个时候,因为settimeout是异步执行的,之前的方法都已经执行完毕,上下文环境又回到了全局对象中,所以如果是执行函数必须是在全局对象中能找到的(我们平时用function xx(){}定义的函数都是被放入全局对象中)。但是楼主定义的JS是属于一个函数体内的私有变量,在该函数执行完毕后该变量已经销毁,而当setTimeout在执行的时候会去全局变量中查找函数,没有找到当然会报错。其次,你的function:JS是定义在匿名函数体内的,属于该匿名函数的私有变量,因为你用var定义了,在该匿名函数之外是不可访问的。你可以尝试稍微改变一下定义:
function(){
var w=this;
JS=function(s){
....
}
window.setTimeout("JS('js2.js')",5000);
}()
这时JS函数就可以执行了,因为定义JS的时候没有用var,js解析器就默认JS这个变量为全局变量。js的全局变量是存放在js的一个全局对象之中的,这个全局对量可以理解成window对象。
所以上述的修改也可以等同于:
function(){
var w=this,JS=function(s){
....
}
window["JS"] = JS;//这里的window["JS"]中的JS随便你定义成什么变量,但你后面setTimeout取的时候必须保持一致。
window.setTimeout("JS('js2.js')",5000);
}()针对楼主的疑问,再统一回答下:
1、function(){
var w=this, JS=function(s){//插入JS
var oh=document.getElementsByTagName('head')[0], os=document.createElement('script');
os.setAttribute('type', 'text/javascript');
os.setAttribute('src', s);
oh.appendChild(os)
};
window.setTimeout("JS('js2.js')",5000);//这里怎么延时执行不了啊?说JS未定义。如果是JS('js2.js')就没有问题,这是为什么啊???
})();
这个是因为window.setTimeout()是异步执行的,而且其上下文环境是整个全局对象(可以理解成window这个对象),而JS函数只是匿名函数中的一个私有变量,在该匿名函数执行完之后就已经销毁释放了。上下文中根本不存在这个变量,所以会报错。window.setTimeout("JS('js2.js')",5000);这据代码放在任何位置都是执行不了的。2、正如楼上所说,如果是带引号的情况下,你没有对JS的作用域进行定义,那么用带引号来引用函数,那么提示的报错当然是未定义,而没有带引号的情况那是你直接调用了函数句柄,所以就不存在问题。
不带引号看你是如何调用了,如果你是用window.setTimeout(JS('js2.js'),5000);那么可能仍然是无法达到你预期的效果,因为你用了JS('js2.js'),这个执行函数的写法,也就是说你赋给setTimeout第一个参数的是执行了JS('js2.js')这个函数后的结果,而你的结果并没有返回任何东西,所以,相当于window.setTimeout(undefined,5000);但是如果window.setTimeout(JS,5000);就可以正常执行了,因为你赋给第一个参数的是一个函数,js引擎会在等待队伍中取出它,并执行这个函数。
首先,LZ的JS函数定义在一个自执行函数中,既形成了一个闭包,JS的作用域就在这个闭包里
其次,setTimeout的作用域固定为window
//这段代码中,JS被执行于window作用域中,而window作用域中没有定义JS函数,所以说JS未定义
window.setTimeout("JS('js2.js')",5000);//这段代码中,JS被执行于闭包作用域中可以被正确执行
JS('js2.js');
解决办法就是:让window作用域中有定义JS函数//直接定义JS为window变量
(function(){
var w=this;
//注意下面一行的定义方法
window.JS=function(s){//插入JS
var oh=document.getElementsByTagName('head')[0], os=document.createElement('script');
os.setAttribute('type', 'text/javascript');
os.setAttribute('src', s);
oh.appendChild(os)
};
window.setTimeout("JS('js2.js')",5000})();
(function(){
var w=this, JS=function(s){//插入JS
var oh=document.getElementsByTagName('head')[0], os=document.createElement('script');
os.setAttribute('type', 'text/javascript');
os.setAttribute('src', s);
oh.appendChild(os)
};
window.setTimeout(function(){JS('js2.js')},5000);//这里怎么延时执行不了啊?说JS未定义。如果是JS('js2.js')就没有问题,这是为什么啊???
})();