哈哈哈开头拿来刺激大家的~
想写一下关于JS中变量提升的知识~先上一段代码
var a = 1;
setTimeout(function(){
a = 2;
console.log(a); //2
}, 0);
var a ;
console.log(a); //1
a = 3;
console.log(a); //3
后面已经标明哪一步会打印出什么来了~但是打印顺序并不是像代码中从上到下的执行,而是在控制台打出1,3,2来。下面是分析代码
var a ; //后面有声明a这个变量,那么就按照变量提升的原则把它改写到前面来
a = 1; //紧接着先给a赋了一个值是1
setTimeout(function(){
a = 2;
console.log(a); //2
}, 0); //setTimeout的代码块执行顺序会延后,我们先把它放在一边,它需要先执行完其他不含有setTimeout的代码之后才会执行
console.log(a); //1 //现在的a是上面声明的全局变量a,已经被赋值为1,所以得到1
a = 3; //此处又给a赋值为3,也就是说现在a的值是3
console.log(a); //3 //此处打印出来的a是3
执行完后两个console.log之后得到了两个数字,OK,现在该轮到setTimeout中的代码了~大家可能会疑惑为什么setTimeout中时间延迟为0秒,我就莫名其妙放在最后才执行了?原因嘛,就是你可以把setTimeout当成一个闹钟,当我的代码中存在setTimeout的时候,我立刻就把它变成一个闹钟放在一边,注意,这里不会去解析setTimeout的延迟时间!浏览器不解析延迟时间!顺序向后执行代码结果就解析出了1和3这两个值,现在回过头来看setTimeout中的代码,这里面的匿名函数给a赋值为2,然后打印a的值就是2,需要注意的一个点是这个匿名函数中直接用了a = 2,这是直接给全局变量a赋值,如果这里是var a = 2那么这里的a就是声明了一个局部变量,在这个匿名函数外部是访问不到的这就涉及到了函数作用域的问题大家可以去找资料看一下下面改写一下
var a = 1;
var a ;
console.log(a); //1
function (){
a = 100;
}
setTimeout(function(){
console.log(a); //2
}, 0);
console.log(a); //3
解析代码
var a ;
function t1(){
a = 100;
} //
a = 1;
console.log(a); //1
setTimeout(function(){
console.log("100"); //100
}, 0);
console.log(a); //1
这里大概就能看明白一些了吧打印顺序是1,1,100,最后一个100就是一个数字,和其他没有关系可能有些绕,解析代码的过程就是:先变量提升,拿到var a和t1(),这里我需要解释一下,变量的声明(也就是var)和function都会被提前,可以理解为“函数提前”吧。。。。毕竟函数是一个对象2333333,然后我们就可以放心大胆的往下看了~然后逐行解析就是看到a被赋值为1,那么第一个console.log(a)就得到了1,第二个console.log(a)存在setTimeout中,先变成闹钟被搁置,然后继续向下看,又
console.log(a)了哈哈哈,还是1,现在开始执行闹钟的内容,就是打出了一个100,然而这个100和t1完全没有关系,t1中声明的一个全局变量a(函数中没有用var 声明的变量统统都是全局变量)已经在后面被a = 1给再赋值了一遍,所以它打印的就是自己定义的一个100(这部分好像废话。。。)再看一个例子~
var a ;
function t1(){
a = 100;
}
a = 1;
console.log(a);
setTimeout(function(){
console.log("a");
}, 0);
a = 200
console.log(a);
大家可以想一下这个执行的顺序和打印的值~