es6学习笔记
-
let和const
es6新增了let命令,使用方式类似var ,均用作声明变量,但是let和var也是有很大的区别的。
1.var存在变量提升,let不存在。会存在暂时性死区
2.var不声明使用,相当于在全局声明变量。let不声明使用会报错。
3.let声明为块级作用域,es5中只有全局作用域和函数作用域,没有块级作用域。
4.let不能重复声明回报错。var重复声明时,会去内存中查找声明的这个变量,如果找到了就把值覆盖,没找到就开辟内存来存放这个变量。
使用let可以解决闭包的问题 ,var li = document.getElementsByTagName('li'); if(li!= null && li != undefined){ for(var i = 0;i<li.length;i++){ li[i].addEventListener('click',function(){ console.log(i); },false) } } //这里打印出来的i 都是li的个数。四个li,则打印出来4个4,这里存在闭包的问题,当函数触发的时候,i已经变成了4,所以每次点击都会打印出来的是4. 解决方法1,使用es5的立即执行函数,每次增加参数,这时点击的时候是取得是立即执行函数的参数。所以便打印的是0 1 2 3 var li = document.getElementsByTagName('li'); if(li!= null && li != undefined){ for(var i = 0;i<li.length;i++){ (function(i){ li[i].addEventListener('click',function(){ console.log(i); },false) }(i)); } } 解决方法2: i声明成为let i= 0; 只要块级作用域内存在let命令,它所声明的变量就“绑定”这个区域,不再受外部的影响。总之,在代码块内,使用let命令声明变量之前,该变量都是不可用的,尽管代码块外也存在相同全局变量, 变量i是let声明的,当前的i只在本轮循环有效 所以每一次循环的i其实都是一个新的变量。你可能会问,如果每一轮循环的变量i都是重新声明的, 那它怎么知道上一轮循环的值,从而计算出本轮循环的值?这是因为 JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算。 var li = document.getElementsByTagName('li'); if(li!= null && li != undefined){ for(let i = 0;i<li.length;i++){ li[i].addEventListener('click',function(){ console.log(i); },false) } }
const命令是常量的声明,声明时就要赋值,一旦声明则不能改变,对于基本类型则是不能改变值,对于复杂数据类型如object类型数据,则是不能修改地址。
var a = 1; let b = 2 console.log(a,window.a); console.log(b,window.b); 输出: 1 1 2 undefined //继续声明b var b = 4; //则会报错 Uncaught SyntaxError: Identifier 'b' has already been declared const c = 5; c = 6; //回报错 Uncaught TypeError: Assignment to constant variable. const d = {name:'zhangsan'}; d.name = 'lisi', console.log(d.name) //输出lisi,这里的地址不变,操作的是地址对应的内存中的数据对象。
2.解构赋值
数组解构
let [a,b] = [1,2,4]
相当于 let a = 1,b=2;
除了数组还可以为set
let [x, y, z] = new Set([‘a’, ‘b’, ‘c’]);
x为 ‘a’
默认值解构这里y存在默认值,null的话不生效,因为null === undefined 为false
let [x, y = ‘b’] = [‘a’, undefined]; // x=‘a’, y=‘b’
对象解构
let {foo,bar} = {foo:‘111’,bar:‘222’}
foo // 111
bar // 222
本人觉着这里最有用的还是解构对象的方法,例如
let { log, sin, cos } = Math; 后续代码中便可以使用log来代替 Math.log,非常之方便。
字符串解构
const [a, b, c, d, e] = ‘hello’;
a // h
数值和布尔值的解构赋值
解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。let {toString : s } = 1;
s === Number.prototype.toString //true
let {toString : s} = true;
s === Boolean.prototype.toString //true函数参数的解构赋值
function add([a,b]){
return a+b;
}
add([1,2])
这里的参数还可以有默认值
function add2({a = 1,b = 2} ){
return a+b;
}
add2() //没有参数,均使用默认参数,则结果为 3
add2(4) //一个参数,默认顺序赋值, 结果为 6
add2(4,5) //两个参数,均使用传入参数,解决为9
这里要注意圆括号的问题
let [(a)] = [1] 这里会报错
let {x: ( c )} = {};
let ({x: c}) = {};
let {(x: c)} = {};
let {(x): c} = {};
let { o: ({ p: p }) } = { o: { p: 2 } };
以上几个表达式均会报错。变量声明语句不能使用圆括号。
赋值语句的非模式部分是可以使用圆括号的
[(b)] = [3]
加上了 let var的话就会报错,有关键字的为声明语句,直接赋值的为赋值语句。