ES6的语法
1、变量声明的方式
let和const
二者的共同点:
- 都是块级作用域
- 在同一个作用域下,变量名不允许重复
- 他们声明的全局变量并没有挂在 window对象上
- 都没有预编译
二者的不同点:
- let 声明的变量值可以改变
- const 声明的变量值不能改变
- const必须声明后立即赋值: const a = 3.14;
- const存引用数据类型时,内容可以发生改变(地址不能改变)
- 优先考虑使用const , 如果变量会发生改变,就使用let , 最后使用var
2、数组的解构
ES6新增了一个结构功能,栗子:
const arr = [1,2,3] ;
const [a , b , c] = arr ;
console.log(a , b , c); // 输出 1 2 3
也就是将数组的元素依次赋值给a,b,c
等价于:
const a = arr[0] ;
const b = arr[1] ;
const c = arr[2] ;
可以跳过一些变量:
const [c , , d] = arr ;
console.log(c , d); //输出 1 3
可以是数组包含数组:
const arr2 = [1,2,[3,4]] ;
const [a,b,c] = arr2 ;
console.log(c); // 输出[3,4]
const arr2 = [1,2,[3,4]] ;
const [a,b,[c]] = arr2 ;
console.log(c); //输出 3
const arr2 = [1,2,[3,4]] ;
const [a , , [ , c]] = arr2 ;
console.log(c); //输出 4
在ES6中交换两个变量的值就不需要在声明一个变量做容器了:
// 交换两个变量的值
let a = 2 ;
let b = 1 ;
// 把等号右边的值给左边
[a , b] = [b , a] ;
console.log(a , b);
这里ES6直接把右边[b,a]的值解析为[1,2]然后赋值给了[a,b]
3、对象的解构
通过解构对象,你可以把它的每个属性与不同的变量绑定,首先指定被绑定的属性,然后紧跟一个要解构的变量。
const obj3 = {
name : 'cc' ,
age : 18 ,
say : function () {
console.log(this.name);
}
}
const {name , age , say} = obj3 ;
console.log(name , age , say);//输出 cc 18 ƒ () { console.log(this.name);}
当对象的属性名和属性值一样时,可简写为:
const a1 = 1 ;
const a2 = 2 ;
const a3 = 3 ;
const obj2 = {
a1 : a1 ,
a2 : a2 ,
a3 : a3
}
// 简写 属性名和属性值是一样的
const obj2 = {
a1 ,
a2 ,
a3
}
console.log(obj2);
如果想再声明一个变量,但是这个变量也不需要从对象中获取值,这个时候,此变量的值就是 undefined
let dog = {
name: 'bobi',
age: 2
}
let { name, age,sex } = dog
console.log(name,age,sex) //输出 bobi,2,undefined
这个时候,可以给他添加一个默认值:
let { name, age,sex='boy' } = dog
如果想重复获取属性值怎么办,若按照以下方法:
let { name, age, sex = 'boy' } = dog
console.log(name, age, sex)
let { name, age } = dog
console.log(name, age)
结果会报错,会提示定义了重复的变量name
解决方法:
let {name:l_name,age:l_age}=dog
console.log(l_name,l_age)
这样就相当于声明变量 l_name 并从对象dog中获取name属性的值赋予此变量;声明变量 l_age, 并从对象dog中获取age属性的值赋予此变量。
按照创建对象字面量的逻辑,name 为键,l_name 为值。但注意,这里是声明变量,并不是创建对象字面量,所以争取的解读应该是:
声明变量 l_name,并从person 对象中找到与 name 同名的属性,然后将此属性的值赋值给变量 l_name
所以,我们最后输出的是变量 l_name和l_age
这种状态下,也是可以给变量赋予默认值的:
let {name:l_name,age:l_age,sex:l_sex='boy'}=dog
嵌套对象的解构赋值
let dog = {
name: 'bobi',
age: 2,
sex:'boy',
look:{
say:'wang'
}
}
// 从对象 dog 中找到 look 属性,并将值赋给变量 look
let {look}=dog
// 从对象 look 中找到 say 属性,并将值赋给变量 say
let {say}=look
console.log(say);
上面代码一层层的进行结构赋值,也可以简写为如下形式
let {look:{say}}=dog
console.log(say);
4、展开运算符(…)
…运算符可以将数组转换成逗号分隔的参数序列
所以,想实现数组的深拷贝,使用展开运算符一行搞定:
const arr = [1,2,3] ;
const arr3 = [...arr] ;
console.log(arr3); // 输出 [1,2,3]
也可展开对象:
const obj = {a:1 , b:2 , c:3} ;
const obj2 = {...obj , name : 'cc'} ;
console.log(obj2); //输出{a: 1, b: 2, c: 3, name: 'cc'}
5、箭头函数
js中的函数类型有具名函数、赋值式函数和匿名函数,其中只有匿名函数可以改写成箭头函数。箭头函数定义包括一个参数列表(零个或多个参数,如果参数个数不是一个的话要用 ( … )包围起来),然后是标识 =>,函数体放在最后。
形参有且只有一个的时候,省略小括号;当函数体只有一句代码且有返回值的时候 , 省略大括号和return
*注:箭头函数中没有arguments,因此使用展开运算符接受实参 …arr 得到的是一个真数组
如:
function fn(n) {
console.log(n);
}
可写为:
const fn = (n) => {
console.log(n);
}
// 当形参有且只有一个的时候,括号可以省略
const fn = n => {
console.log(n);
}
// 如果有两个参数,不能简写
const fn2 = (n , m) => {
console.log(n + m);
}
// 当函数只有一句代码,且有返回值的时候,可以省略大括号和return
const fn3 = n => {
return ++n ;
}
const fn3 = n => ++n ;
const fn4 = (...a) => {
// 在箭头函数中没有arguments,用展开运算符传参
console.log(a); // 真的数组
}
fn4(1,2,3,4,5)
*注:使用箭头函数语法替代其他普通的多行函数,特别是那些通常会被自然表达为函数声明的情况,是不合理的。=> 箭头函数转变带来的可读性提升与被转化函数的长度负相关。这个函数越长,=> 带来的好处就越小;函数越短,=> 带来的好处就越大。
箭头函数的this指向
箭头函数没有定义this绑定,父元素指向谁,箭头函数的this就指向谁
const fn = () => {
console.log(this); // 此处this指向window
}
document.onclick = () => {
console.log(this); // 此处this指向window
}
const obj = {
// name : this , // 此处this指向window
name : 'yy' ,
speak : function () {
console.log(this); // 此处this指向obj
},
say : () => {
console.log(this); // 此处this指向window
} ,
talk : function () {
console.log(this); // 此处this指向obj
setTimeout( () => {
console.log(this); // 此处this指向window
console.log(this.name);
},100)
}
}
document.onclick = function () {
console.log(this); // 此处this指向document
setTimeout(function () {
console.log(this); // 此处this指向window
})
setTimeout(() => {
console.log(this); // 此处this指向document
})
}
在函数中,this指向就可能发生改变:
事件处理函数 => 事件源
对象的方法中(函数) => 对象本身
其他函数 => window
*而箭头函数在意义上面来说没有this。 如果使用了this 那么就一定是外层this ,不会自动指向window对象。
在ES6中,会默认采用严格模式,因此this也不会自动指向window对象了,而箭头函数本身并没有this,因此this就只能是undefined。
6、参数的默认值
在ES6中,如果想给函数的参数添加默认值,就不需要用短路赋值了,直接在括号中添加即可:
// 给参数添加默认值
function fn(a = 0 , b = 0) {
return a + b
}
console.log(fn(1,2));