JS 函数的执行时机
JS函数在不同的时候运行,会有不同的运行结果
本文将分别举例分析
案例一
let a = 1
function fn(){
console.log(a)
}
复制代码
这里不会打印任何东西,因为函数只是声明了,但是没有执行
案例二
let a = 1
function fn(){
console.log(a)
}
fn() // 1
复制代码
这里会打印a, 因为一开始声明了 a , a 的值为1,然后调用函数 fn , 打印 a。
案例三
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
关于setitmeout的通俗理解
你正在打游戏,还剩下最后一关,这时候你妈妈让你去吃饭,你嘴上说马上(对应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
一定要记住,函数声明和函数调用是两回事,在函数调用前,函数声明里使用的变量的值可能已经发生变化
闭包
一个函数和它使用的函数外部的变量就组成了闭包
闭包可以让你从内部函数访问外部函数作用域
关于闭包的更多细节:
developer.mozilla.org/zh-CN/docs/…
本文为fjl的原创文章,著作权归本人和饥人谷所有,转载务必注明来源
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END