let const var的区别 ,什么是块级作用域,如何用ES5的方法实现块级作用域(立即执行函数),ES6 呢
在ES6之前是如何实现块级作用域:立即执行函数。
最简单的方法:匿名函数自调用
function a(){ (function(){ for(var i=0;i<3;i++){ console.log(i); } })(); console.log(i); //输出undefined } a();
首先,说var一般用来声明全局变量,并不是说var声明的变量就是一个全局变量。
我们可以将其理解为一个约定俗成的习惯,也就说,我们一般习惯性地用var来声明全局变量。
做个测试很容易就会知道,var声明的变量在作用域上并不一定是全局变量。
大家都知道,在一个函数中,即使是用var来声明一个变量,在这个函数外,也依然无法访问到这个变量。而我们在全局作用域下,即使是用let声明一个变量,也依然可以在下面的函数中访问到这个变量。
因此,决定一个变量是究竟是全局变量还是局部变量的不是var或者let,而是这个变量所处的环境。
作用域可以分为全局作用域和局部作用域。也可以分为一个个块级作用域。
全局作用域就是刚刚进入这个环境,局部作用域通常就是一个函数的函数体。
块级作用域通常指的是{}内部的区域。
块级作用域通常不去和全局作用域、局部作用域并行考虑。因为它们在概念上是有交叉的。
if可以形成一个块级作用域,while可以,一个函数当然也可以。但是通常只有函数可以形成局部作用域。
1. 首先,var声明的变量会进行变量声明提升的处理。
什么意思?就是说,我们在var a = 1之前就可以访问到这个变量。只是这时的变量仅仅是被声明了出来,访问一个仅仅被声明的变量会打印undefined。初始化的操作还要等到执行到对应的赋值语句才可以。
而let、const声明的变量就不存在声明提升。如果我们在let a = 1;之前访问a,就会直接报错。
2. let、const仅在其所在的块级作用域生效,而var是不会受到一个单纯的块级作用域影响。也就是说,在if语句内用let、const定义一个变量,在if语句之外是访问不到的,但是在if内用var定义的变量,在if语句之外就可以访问到。
如果是一个局部作用域,也就是一个函数体内,在这时,不论是用let、const还是var,我们都不可能在函数体之外访问到。
3. var、let声明的变量可以被重新赋值,const声明的基本类型常量不可以重新复制,但声明的引用类型对象,不可以更改对 对象 的引用,但是可以更改对象内部的数据。
const创建的是一个普通类型的变量,我们不可以改变这里面保存的数据,但是如果存储的是引用类型的数据,我们依然可以改变数据中存储的属性。
这里要注意了,对于const来说,不可以改变的仅仅是栈内存中保存的值。如果const指向的是一个引用类型的变量,首先,引用类型的数据是保存在堆内存的,然后堆内存的地址会被保存在栈内存中。当我们去修改一个对象里面的属性值时,改变的仅仅只是堆内存中的数据,这段内存所对应的地址当然还是不会改变的,所以,栈内存中保存的变量也就不会发生变化。
4. var声明的变量可以被再次声明,而let、const就不可以,当然var和let也不能重复声明一个变量
5. 没声明就使用一个变量提示not defined,在let、const声明之前使用报错:cannot access....,var声明变量之前被使用值为undefined