一、let与var的区别

(1)作用域不同(处在不同类型作用域的同名变量,变量结果互不影响)

var是在es5中用来声明变量。var声明的变量的作用域分为:全局作用域和函数作用域。

第一,在函数体里面用var声明的变量,变量作用域属于函数作用域。

特点是:作用结果对函数体外的同名变量不起作用。

第二,在函数体外面用var声明的变量,变量作用域属于全局作用域。

特点是:不在函数体里面的循环体,用var声明的变量也属于全局变量,与循环体外同名的全局变量属于同一作用域,变量结果相互影响。

第三,在函数体()里面,引用没有重新声明的同名的全局变量作为函数参数的,属于函数变量。

特点:这个函数体内的同名变量的作用结果,不影响函数体外的全局变量。

let是在es6中用来声明变量。let声明的变量的作用域分为:全局作用域和函数作用域、块级作用域。

第一点,同上。

第三点,同上。

第二点,在函数体外面用let声明的变量,变量作用域属于全局作用域。

特点是:1>同名的全局变量,变量结果相互影响。

               2>循环体()内,没有用let重复声明的变量,变量作用域属于全局作用域。

               3>在满足2>的前提条件下,循环体{   }内,没有用let重复声明的变量,变量作用域属于全局作用域。

第四点,在循环体{ }内或者在循环体()内的用let声明的变量,变量的作用域属于块级作用域。

特点是:1>变量结果,影响不了循环体外的同名的全局变量或者函数变量。

               2>在循环体()用let声明的变量,属于父级级别的块级作用域。

               3>在循环体{     }用let声明的变量,属于子级级别的块级作用域。

               4>父级级别的块级作用域 和同名变量的 子级级别的块级作用域,变量结果互不影响。

(2)let没有变量提升

let必须先声明,后使用。不然直接出bug。

但是,var先声明,后使用。不会出bug,只会出现undefined或者NaN之类。

(3)let不能重复声明

在同一个作用域范围内,变量不能用let重复声明,不然直接报错。

(4)es5和es6的经典循环

经典循环:在一个for循环体内,有一个异步函数体。

特点:1>es5的for循环体()内,用var声明变量i,属于全局作用域。异步函数体里面,直接输出打印变量i。

               由于es5没有块级作用域,所以都属于全局作用域。

               主线程for循环体代码结束后,变量结果,影响到异步函数体的代码执行结果。 

           2>es6的for循环体()内,用let声明变量i,属于父级级别的块级作用域。异步函数体里面,直接输出打印变量i。

               由于es6有块级作用域,所以属于子级级别的块级作用域。

               主线程for循环体代码结束后,变量结果,不会影响到异步函数体的代码执行结果。

(5)利用闭包,改变变量作用域的类型

闭包格式:function(形参){    异步函数体    }(实参);

原理:闭包能形成一个不销毁的栈环境,也就是受匿名函数的作用域保护。变量只能通过匿名函数改变。

          形参+实参+es5异步函数体放到{  }里面,使得异步函数体里面的全局变量,改变成函数变量。

特点是:让es5的异步函数内外的同名变量的作用域互不干扰。

            

原文地址:https://www.cnblogs.com/Strugglinggirl/p/15211066.html