JavaScript单线程,异步以及let const var的讨论

在es6之前,我们定义变量都是用的var的方式,但是我确实花了不少的时间理解var的变量定义方式,var定义变量的作用域是整个函数范围,而不是类似于c语言的在一个大括号内,严谨的说也就是没有所谓的“块级作用域”,这被视为是JavaScript的一个缺点,如下代码:

  for(var i=0;i<3;i++)
       {
       setTimeout(function(){
       console.log(i);
       },200)
       }//结果为3,3,3


在了解到闭包,垃圾回收机制之前我对这个结果并不是很理解,但是现在回过头来看就比较清晰了,当然,用到了setTimeout,就必须得先扯开一下聊聊JavaScript的语言特性,首先

它是一门单线程,异步的语言,所谓单线程,就是说JavaScript只能再一个时间内做一件事,举个实际的例子来说,昨天早上我起床叫我室友打LOL,他先起床,后刷牙,耗时7分钟,最后打开电脑等待游戏登陆的3分钟,总耗时10分钟。这样明显会使得做事的效率明显比较低,于是他今天早上学聪明了,起床直接打开游戏登陆,再去刷牙,只用了7分钟,节约了3分钟宝贵的游戏时间,这也就是“异步操作”。那么JavaScript到底是如何做到的呢,实际上,JavaScript,c语言(其他语言我也不晓得~~)的函数的编译原理都是基于“堆栈”这种数据结构的,编译器会把需要执行的函数放入stack中执行则入栈,return则出栈,所以对于某些函数,方法,JavaScript会让它处于等待状态,不会等到它出栈后再让后续函数入栈。

其次:

在JavaScript中有垃圾回收机制,由于对地址的回收,类似于c语言的free函数,至少对于初学者,这是一个优点,但是便利的结果往往是更加纠结,关于这个有趣的机制MDN给出了详细的解释

内存管理 - JavaScript | MDN

由此可见,在我们给出的这个例子里,i实际上是一个引用也就是指针,for循环先执行完毕后定时器函数执行,当定时器函数执行时,由于它的内部没有定义i,所以他会沿着他的作用域链寻找i,而此时for循环已经被垃圾回收了,所以i最后的值为for循环结束累加的值;

如何解决这个问题呢,此前我们会利用闭包的方法,将函数嵌套,让i存在引用的对象,也就不会被垃圾回收了,代码如下:

for(var i=0;i<3;i++){
      (function(){
           var fn1=(x)=>{
           console.log(x);
       }
       return fn1(i);
      })()
     }//0,1,2


var某些特性解释让代码看起来如此复杂~~~;

那么let将如何解决这个问题呢?

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


是不是感觉柳暗花明又一村的,和c语言写循环是一样的,明显的感觉到JavaScript与其他语言相比其独具风格的地方在变少;

综上所述:

let,const的与var的区别在于,var的作用域在整个函数,而前者的作用域仅在父级的大括号;

当然还有其他的小区别:

1:var 会在定义的函数未执行时就被找到,如

     

  alert(i);//undefined
  var i=2;


 而换成let const就会报错

2: const 定义的变量为常量,不可以改变,会报错,同样用let重定义变量会抛出一个语法错误;

3:形如for (let x...)的循环在每次迭代时都为x创建新的绑定。

/*也就是说循环创建的每一个i并不等效,i的值的改变并不是在单纯的在原引用上改变;

参考资料

深入浅出ES6(十四):let和const_JavaScript_Jason Orendorff_InfoQ精选文章

js中的同步和异步的个人理解_js什么是同步什么是异步_YinghaoGuo的博客-CSDN博客

---------------------文章转载至:  用月光取暖----------------------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值