进入前端领域工作将近两年,看过学习过很多大牛的文档和视频,2018年也打算对学过的知识点给出一个小结式的输出,从ES6开始吧。
ES6新增 let 命令,用途是用来声明变量。一个新的事物被提出,总是有原因的,它能带来什么?ES6之前是用 var 声明变量,它有什么不足呢?
不足一:用来计数的循环变量泄露为全局变量。看半天文字,不如敲两行代码来的快:
var aa = [];for(var i=0;i<10;i++){ aa[i] = function(){ console.log(i); }}aa[8](); //10 不论是aa[5]()还是aa[6]()输出都是10复制代码
上面代码中,变量 i 是 var 声明的,在全局范围内都有效,所以每一次循环,新的 i 值都会覆盖旧值,导致最后输出的是最后一轮的 i 值。
如果把 for 里面的 var 换为 let,则 i 是 let 声明的,当前的 i 只在本轮循环有效,所以每一次循环的 i 其实都是一个新的变量,则aa[8] ()输出的就是8,aa[5] ()输出的就是5。这就引出了块级作用域的概念。
块级作用域的简单理解:任何一对花括号({ })中的语句都属于一个块,在花括号里面用 let 定义的所有变量在花括号外都是不可见不可用的。为了更好理解,再来一个例子:
function f1(){ let n=5; if(true){ let n=10; } console.log(n);}f1(); //输出5 表示外层代码块不受内层代码块的影响 复制代码
function f2(){ var n=5; if(true){ var n=10; } console.log(n);}f2();//输出10 表示内层变量会覆盖外层变量复制代码
不足二:用 var 声明的变量存在变量提升
什么是变量提升?
变量提升是指将函数及变量的声明将被提升到函数最顶部。
变量可以先使用再声明,也就是变量可以先使用再声明。举个例子:
var a=1;(function(){ console.log(a); var a=2; })() //undefined复制代码
原因:代码块(函数内)里面声明并定义了一个变量 a,导致变量提升了,实际代码的执行顺序如下:
var a=1;(function(){ var a; console.log(a); a=2; })() //undefined 声明了a,但是还没有定义,所以是undefined复制代码
如果用 let,会报错,提醒你使用之前先声明
let a=1;(function(){ console.log(a); let a=2; })() //"error" "Use before declaration (line 25)"复制代码
上述两点看懂后,对 var 和 let 会有一个比较清晰的认识,下面再简单介绍一下 const 命令:它是用来声明常量,一旦声明,其值就不能改变。
- 不可修改
const name = '小花';name = '小草'; //error 复制代码
2.只在块级作用域内起作用,不存在变量提升,先声明后使用,和let关键字一样
3.不可重复声明同一个变量,声明后必须赋值
如果常量是一个对象,如何处理,这是一个重点
const Person = { "name": "小花"};Person.name = "小草";Person.age = 18;console.log(Person); //{ name: "小草”,, age: 18}复制代码
是不是很奇怪,不是说常量的值是不能改变的吗?为什么 Person 的 name 被改了?
对于这种复合类型的变量,变量名不指向数据,而是指向数据所在的地址。const 命令只是保证变量名指向的地址不变,并不保证该地址的数据不变。
参考资料:
1.《ES6标准入门》 阮一峰 著
2.微信公众号---web前端教程