在es6以前咱们咱们声明一个变量用var如:javascript
var a = 1; var arr = [1,2,3]; ...
es6以前呢javascript没有块级做用域,如何来理解呢:就是在代码块里声明的变量会“变量提高”至就近的函数做用域顶部或全局当中。如咱们熟悉的for循环:java
for( var i=0; i<10; i++){ console.log(i) } # 提高到全局,至关于 var i; for(i=0; i<10; i++){ console.log(i) } function test (){ ..... for( var i=0; i<10; i++){ console.log(i) } } # 提高到函数做用域顶部,至关于 function test (){ var i; ..... for(i=0; i<10; i++){ console.log(i) } }
在es6中给出了块级做用域的概念:{}所包涵的代码块就是一个做用域。同时又给出了另外两个变量声明的关键字:let和const。es6
let与var同样,也是用来声明变量的,但它有着更好的做用域规则。来看几个栗子:函数
function test1(){ for(var i=1;i<3;i++){ console.log(i); } console.log(i); // 3 } test1(); function test2(){ for(let i=1;i<3;i++){ console.log(i); } console.log(i); // 报错了 } test2();
执行test1的时候,因为变量提高了所已外面的log能找到i,而test2用的let声明的变量,在for循环的代码块内生效,for循环结束后变量被销毁,被垃圾回收机制回收。因此会报错。code
let另一个值得注意的是,不能重复声明变量:对象
let a = 1; let a = 3; // 报错 Uncaught SyntaxError: Identifier 'a' has already been declared
与let不一样之处在于,const声明的变量只能够在声明时赋值,不可随意修改,不然会致使语法错误。ip
const PI=3.1415926; //ok const G; G = 9.8; // SyntaxError: Missing initializer in const declaration const MODIFY = 1; MODIFY = 2; // TypeError: Assignment to constant variable.
上面能够看到声明的时候必须赋值不然回报没有初始化的错误,已赋值的常量再次赋值也会报错。
咱们怎么理解下面这段代码呢作用域
function test(){ const obj={ name: 'lilei' } obj.age=20; console.log(obj); // {name: "lilei", age: 20} } test()
const声明的变量不是不能修改吗,这里怎么能够修改为功呢,咱们知道对象是引用类型,咱们修改的是值,而不是其引用,而const声明的对象类型的变量保存的是其引用,因此是不矛盾的。it