JS 函数的执行时机

简介: JS 函数的执行时机

JS 函数的执行时机


前言

JS函数在执行的时候,函数所处的位置不同,执行的结果就会各不相同。

下面我们通过几个例子来看一下,函数的执行时机对结果会产生怎样的影响。

正文

例1

let a = 1
function fn(){
    console.log(a)
}
复制代码

唐僧: 徒儿,请问上例会打印出多少?

悟空:不知道,因为你压根没有调用函数fn。

例2

let a = 1
function fn(){
    console.log(a)
}
fn()
复制代码

唐僧: 徒儿,请问上例会打印出多少?

八戒:很显然,是1。

例3

let a = 1
function fn(){
    console.log(a)
}
a = 2
fn()
复制代码

唐僧: 徒儿,请问上例会打印出多少?

沙僧:因为fn在a=2后执行,故打印出2。

例4

let a = 1
function fn(){
    console.log(a)
}
fn()
a = 2
复制代码

唐僧: 徒儿,请问上例会打印出多少?

白龙马:对比一下例3我们可以知道,fn先调用的,故会打印出1。

前面几个例子都比较简单,相信大家都可以回答出来。那么我们现在升级一下难度,请看下面这个:

猛料

函数执行的时机不同,运行结果也不同

所谓时机不同,结果不同~

let i = 0
   for(i = 0; i<6; i++){
     setTimeout(()=>{
       console.log(i)
     },0)
   }
   //结果输出6个6
复制代码

上面的代码中, console.log(i)打印的结果是6个6,而不是0,1,2,3,4,5。 这里便用到了调用时机,下面有图有真相。

可以这样理解
  • 因为JS是单线程的,单线程就意味着所有任务需要排队,前一个任务结束后,才会执行后一个任务。
  • 同步任务:上一件事情没有完成,继续处理上一件事情,只有上一件事情完成了,才会做下一件事情 –> JS中大部分都是同步编程。
  • 异步任务:规划要做一件事情,但是不是当前立马去执行这件事情,需要等一定的时间,这样的话,我们不会等着他执行,而是继续执行下面的操作。

所以在for循环时

  1. 先赋值i的值为0
  2. 然后判断是否 i<6 ? 如果满足条件会继续进入下一个循环。
  3. setTimeout()代码到了这里会等一会执行,这里便会跳过继续执行i++
  4. 执行i++,此时i赋值为1.
  5. 继续判断i<6,满足进入第二个循环.
  6. .
  7. .
  8. .
  9. 直到执行i++,i的值是6时,不满足i<6.
  10. 跳出循环
  11. 执行第一次循环的setTimeout() //打印出i
  12. 执行第二次循环的setTimeout() //打印出i
  13. 执行第三次循环的setTimeout() //打印出i
  14. 执行第四次循环的setTimeout() //打印出i
  15. 执行第五次循环的setTimeout() //打印出i
  16. 执行第六次循环的setTimeout() //打印出i
  17. 结束,打完收工现在可以看出,由于setTimeout()的执行时间为for语句执行后,所以每次打印出的结果都为6

到了这里便需要介绍以下setTimeout()

setTimeout函数用来指定某个函数或某段代码,在多少毫秒之后执行

代码到了这里时会把函数放在任务队列中,当JS引擎线程空闲时并达到指定时间时,才会把函数放到JS引擎线程中执行。

就算setTimeout()的时间参数为0时,也必须等到当前代码(执行栈)执行完,主线程才会去执行它指定的回调函数。

for循环在主线程内,setTimeout是异步方法,在任务队列里面,只有主线程执行完后,任务队列才执行,当for执行结束时候,此时的i值已经是6,所以得到结果是个6。

那么如何输出0-5呢

for(let i = 0; i<6; i++){
     setTimeout(()=>{
       console.log(i)
     },0)
   }

这是JS后来为新人开发者改变的一个东西。让代码按着新人的思路来实现。 出了上面这种方法能够实现打印0-5

其他方法

1、可以通过自执行函数来实现

for (var i = 0; i <= 5; i++) {
        !(function (j) {
          setTimeout(function print() {
            console.log(j);
          }, 0);
        })(i);
      }
  1. 通过setTimeout第三个参数
for (var i = 0; i < 6; i++) {
        setTimeout((i) => console.log(i), 0, i);
      }



相关文章
|
1月前
|
JavaScript 前端开发 Java
[JS]同事:这次就算了,下班回去赶紧补补内置函数,再犯肯定被主管骂
本文介绍了JavaScript中常用的函数和方法,包括通用函数、Global对象函数以及数组相关函数。详细列出了每个函数的参数、返回值及使用说明,并提供了示例代码。文章强调了函数的学习应结合源码和实践,适合JavaScript初学者和进阶开发者参考。
43 2
[JS]同事:这次就算了,下班回去赶紧补补内置函数,再犯肯定被主管骂
|
1月前
|
前端开发 JavaScript 开发者
除了 Generator 函数,还有哪些 JavaScript 异步编程解决方案?
【10月更文挑战第30天】开发者可以根据具体的项目情况选择合适的方式来处理异步操作,以实现高效、可读和易于维护的代码。
|
2月前
|
JavaScript 前端开发
JavaScript 函数语法
JavaScript 函数是使用 `function` 关键词定义的代码块,可在调用时执行特定任务。函数可以无参或带参,参数用于传递值并在函数内部使用。函数调用可在事件触发时进行,如用户点击按钮。JavaScript 对大小写敏感,函数名和关键词必须严格匹配。示例中展示了如何通过不同参数调用函数以生成不同的输出。
|
2月前
|
存储 JavaScript 前端开发
JS函数提升 变量提升
【10月更文挑战第6天】函数提升和变量提升是 JavaScript 语言的重要特性,但它们也可能带来一些困惑和潜在的问题。通过深入理解和掌握它们的原理和表现,开发者可以更好地编写和维护 JavaScript 代码,避免因不了解这些机制而导致的错误和不一致。同时,不断提高对执行上下文等相关概念的认识,将有助于提升对 JavaScript 语言的整体理解和运用能力。
|
2月前
|
JavaScript 前端开发
js教程——函数
js教程——函数
48 4
|
2月前
|
存储 JavaScript 前端开发
js中函数、方法、对象的区别
js中函数、方法、对象的区别
23 2
|
2月前
|
JavaScript 前端开发 Java
【javaScript数组,函数】的基础知识点
【javaScript数组,函数】的基础知识点
31 5
|
2月前
|
JavaScript 前端开发
Node.js 函数
10月更文挑战第5天
26 3
|
2月前
|
前端开发 JavaScript
探索JavaScript函数基础
探索JavaScript函数基础
23 3
|
2月前
|
存储 JavaScript 前端开发
JavaScript数据类型全解:编写通用函数,精准判断各种数据类型
JavaScript数据类型全解:编写通用函数,精准判断各种数据类型
52 0