JS中的函数使用
一、setTimeout:
格式:
var intervalID = scope.setTimeout(function[, delay, param1, param2, ...]) // 参数在延时时间到达后,将作为该函数的传参,但是在不同浏览器存在兼容性问题,若需使用需做兼容性处理,具体参考链接1
var intervalID = scope.setTimeout(function[,delay])
var intervalID = scope.setTimeout(code[,delay]) // 这里的code为字符串,例如"alert('hello world')",不推荐此方法,有安全风险,,来自MDN网站
delay为需要延迟的时间,单位为毫秒(可选参数,忽略该参数,则delay取默认值0,将立刻执行或尽快执行,实际的延迟时间可能比期待的delay值长;
function为延迟一定时间后执行的函数
链接1
如何在延迟时间到达前停止setTimeout函数执行:
var t = setTimeout(function[,delay]);
clearTimeout(t); // 停止上面计时器内部函数的执行
功能:通常在延迟一定时间后仅执行一次,但是也可以实现间隔一定时间循环执行的功能
代码实践:
1、延迟3秒弹出一次警示框
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type='text/javascript'>
setTimeout(alert_Action, 3000);//setTimeout('alert_Action()', 3000);/ setTimeout(alert_Action(), 3000)//这种写法会立即执行
var alert_Action = function(){
alert('我将在3秒后弹出');
}
</script>
</heaad>
<body>
<h1>JS输出HTML内容</h1>
</body>
</html>
代码执行 结果
2、间隔1秒打印一次信息
(在函数内部调用自身,就可以实现无限次数执行该函数)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type='text/javascript'>
var num = 0
function countNum() {
console.log('当前的num值为:' + num);
num++
setTimeout(countNum, 1000);
}
countNum()
</script>
</heaad>
<body>
<h1>JS输出HTML内容</h1>
</body>
</html>
代码执行结果
3、间隔一定时间打印一次,指定打印次数
(使用for循环限制执行函数的次数)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type='text/javascript'>
var num = 0
function countNum() {
console.log('当前的num值为:' + num);
num++
}
for(let i = 0;i < 13;i++){
setTimeout(countNum, 1000 *(i+1));
}
</script>
</heaad>
<body>
<h1>JS输出HTML内容</h1>
</body>
</html>
代码执行结果
4、在学习的过程中意外的发现了一个坑:
js中延迟打印for循环,如果打印的信息是动态改变的,最后打印出来的结果都是同一个,具体见下面的代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type='text/javascript'>
for(var i=0 ; i<10; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}
</script>
</heaad>
<body>
</body>
</html>
代码执行结果:10个10
但是下面这组代码同样也是延迟打印for循环,却能正确打印我们想要的信息
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type='text/javascript'>
for (let i = 0; i < 10; i++) {
(function (i) {
setTimeout(function () {
console.log(i);
}, 1000);
})
(i);
}
</script>
</heaad>
<body>
</body>
</html>
代码执行结果:0 1 2 3 4 5 6 7 8 9
导致这种差异的原因是什么呢,于是我就去晚上各种搜索,发现原因如下:
1、JS引擎就是以单线程的机制来运行代码,setTimeout()该函数是属于异步执行的,当执行到setTimeout()代码时,会将该函数放在队列中,由专门负责计时的线程开始计时,计时完毕并在同步任务执行结束后,会通知执行代码的线程执行setTimeout()内的代码。在这里for循环一共执行10次,因此队列中依次放了10个待执行的setTimeout函数,执行该函数前for循环已经执行完毕。
2、var 与 let 在for循环中的区别
for(let i = 0;i < 10;i++){ // let 为块级变量,只在for循环内部起作用
console.log('i',i);
}
当i = 0 和i = 1时声明的变量i是不同的,这里for循环执行结束后,会有10个不同的变量,他们的值分别为0-9
for(var i = 0;i < 10;i++){ // var声明的为全局变量
console.log('i',i);
}
var 声明的变量是全局变量,在整个脚本中都可以用,for循环每执行一个迭代,i都会重新赋值,并覆盖初值,for循环结束的结果为一个变量 i = 10,队列中10个setTimeout函数内部的i都指向了同一个i ,故最后打印10个10;
而let 声明的为块级变量,只在当前的for循环中有效,并且在for循环中每次迭代let 都是重新创建一个变量,并不会覆盖之前的变量,因此for循环结束后,会有10个变量,它们的值依次为0-9;
这也解释了为什么这两种方式打印for循环时的结果一个是10个10,一个是一次打印0-9
在这里放一下我看的几个文章的链接:
一文看懂JS的异步在for循环中var和let的区别在for循环中使用let和var的区别
二、setInterval
格式:
var intervalID = scope.setInterval(func, delay, [arg1, arg2, ...]);
var intervalID = scope.setInterval(code, delay); // 与setTimeout()相似,该方法存在安全风险,不推荐使用,来自MDN网站
与setTimeout相似,函数内部代码开始执行的时间可能会晚于delay毫秒
setInterval方法可以传递参数,如下面代码所执行的那样
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type='text/javascript'>
function f() {
for (let i = 0; i < arguments.length; i++) {
console.log(arguments[i])
}
}
setInterval(f,1000,'hello world','aaaaaaaaa','bbbbb','ccccc','dddddddd')
</script>
</heaad>
<body>
<h1>JS输出HTML内容</h1>
</body>
</html>
代码执行结果:每间隔1秒会打印一次 ‘hello world’,‘aaaaaaaaa’,‘bbbbb’,‘ccccc’,‘dddddddd’
功能:每次调用同一个函数无限循环执行,delay时间已经包含了代码运行时间,也就是相邻两次调用该函数的时间为delay毫秒。
如何结束该函数的执行:
var intervalID = setInterval(func, delay, [arg1, arg2, ...]);
clearInterval(intervalID) // 停止setInterval的循环执行