《JS 函数的执行时机》

535 阅读2分钟

JS 函数的执行时机

JS函数在不同的时候运行,会有不同的运行结果 本文将分别举例分析

案例一

let a = 1
function fn(){
    console.log(a)
}

这里不会打印任何东西,因为函数只是声明了,但是没有执行

案例二

let a = 1
function fn(){
    console.log(a)
}
fn() // 1 

这里会打印1, 因为一开始声明了 a , a 的值为1,然后调用函数 fn , 打印 1。

案例三

let a = 1
function fn(){
    console.log(a)
}
a = 2
fn() // 2

这里会打印2, 因为在调用fn()之前,a 被赋值为2

小结:

从以上的例子可以看出,我们在调用函数时,需要仔细注意其中用到的变量值是不是我们需要的值

异步的案例

案例一

let a = 1
function fn(){
    setTimeout(()=>{
        console.log(a)
    },0)
}
fn() // 2
a = 2

setTimeout会等到当前代码执行完毕后,再执行,即执行完let a= 1, fn(), a=2之后,再执行console.log(a) 所以打印出来a是2

案例二

for(var i = 0; i<6; i++){
    setTimeout(()=>{
        console.log(i)
    },0)
}
//会打印出6个6

以上代码会打印出6个6, 原理是:setTimeout会等到当前代码的for循环执行完了,再去执行console.log(i) 而for循环执行完之后,i已经是6了 所以会打印出6个6

关于setTimeout的通俗理解

你正在打游戏,还剩下最后一关,这时候你妈妈让你去吃饭,你嘴上说马上(对应setTimeout(function, 0)),但其实会把游戏打完之后再去吃饭。

案例三

如果希望在for循环使用setTimeout时,能够依次打印出0,1,2,3,4,5,怎么写呢?

for(let i = 0; i<6; i++){
    setTimeout(()=>{
        console.log(i)
    },0)
}
// 0 1 2 3 4 5

用Let就可以了,let 会单独创建一个作用域 相当于有6个 i ,相当于以下代码

(let i = 0) {
    setTimeout(()=>{
        console.log(i)
    },0)
}

(let i = 1) {
    setTimeout(()=>{
        console.log(i)
    },0)
}

(let i = 2) {
    setTimeout(()=>{
        console.log(i)
    },0)
};
(let i = 3) {
    setTimeout(()=>{
        console.log(i)
    },0)
}

(let i = 4) {
    setTimeout(()=>{
        console.log(i)
    },0)
}

(let i = 5) {
    setTimeout(()=>{
        console.log(i)
    },0)
};

案例四

除了使用Let,还可以这样解决:相当于每次把i保存下来

for (var i = 0; i < 6; i++) {
    setTimeout((function(i){
        return function() {
            console.log(i);
        }
    }(i)),0)
}
// 0 1 2 3 4 5

一个套娃案例

function f1(){
    let a = 1
    function f2(){
        let a = 2
        function f3(){
            console.log(a)
        }
        a = 22
        f3()
    }
    console.log(a)
    a = 100
    f2()
}
f1()

会输出1和22 一定要记住,函数声明和函数调用是两回事,在函数调用前,函数声明里使用的变量的值可能已经发生变化

闭包

1592897145974-f769066c-d114-489e-9d36-a02a465a98af.png 一个函数和它使用的函数外部的变量就组成了闭包
闭包可以让你从内部函数访问外部函数作用域

关于闭包的更多细节: developer.mozilla.org/zh-CN/docs/…

本文为fjl的原创文章,著作权归本人和饥人谷所有,转载务必注明来源