ES6常用语法

336 阅读6分钟

let和const

let和const是声明变量,代替var,不同的是let和const会创建一个块级作用域{},不属于全局变量,常用于if,for的块级作用域中。

let a = 0;
console.log(a); // undefined
var b = 1;
console.log(b); // 1

var创建的for循环,只执行一次var i = 0声明。let和const声明的for循环,每次循环时都会生命一次,并把上次循环的结果进行赋值。

  • var有变量提升,先被创建并初始化,赋值为undefined
  • let和const虽然有提升会先创建,但不会被初始化,直到声明语句执行的时候才被初始化,创建到初始化之间的代码片段就形成了暂时性死区
  • 初始化时,let声明如果没有赋值,会默认为undefined,const必须在初始化时赋值
  • const是声明一个常量,值不能改变,被修改会报错。
  • 不允许重复声明

箭头函数

箭头函数 => 用来定义函数,特点:

  • 没有arguments
  • 没有prototype属性,不能作为构造函数,不能用new关键字调用
  • 没有自己的this,它的this指向外层执行上下文的this,即使使用call,apply,bind也无法改变

箭头函数可用来解决需要显示声明保存一个this的操作,如var that = this

//用法,=>之前是()或者参数,=>之后是返回值表达式或{}函数体
()=>1
v=>v+1
(a,b)=>a+b
()=>{
    alert("foo");
}
e=>{
    if (e == 0){
        return 0;
    }
    return e;
}

iterator迭代器

可以迭代的数据类型为:Array,Map,Set,String,TypedArray(类数组),函数的 arguments 对象,NodeList 对象

可迭代的数据原型上有一个Symbol.iterator属性(iterator接口),是一个函数,执行后会返回iterator对象(迭代器对象)

iterator迭代器有一个next方法可以调用,返回一个新对象,有value和done两个属性,value是每次迭代的返回值,done表示是否再次循环,当value为undefined时,done为true表示循环终止。

let arr = [1,2,3]
let iterator = arr[Symbol.iterator]()
iterator.next() // {value: 1, done: false}
iterator.next() // {value: 2, done: false}
iterator.next() // {value: 3, done: false}
iterator.next() // {value: undefined, done: true}

解构赋值

解构赋值可以直接使用对象的某个属性,而不需要通过属性访问的形式使用。

数组解构的原理是消耗数组的迭代器,把生成对象的value属性的值赋值给对应的变量。

一个用途是交换变量,避免要声明一个临时变量值存储值。

let a = 1
let b = 2
[a, b] = [b, a]
console.log(a) // 2
console.log(b) // 1

var foo = ["one", "two", "three", "four"];
var [one, two, three] = foo;
console.log(one); // "one"
console.log(two); // "two"
console.log(three); // "three"

//如果你要忽略某些值,你可以按照下面的写法获取你想要的值
var [first, , , last] = foo;
console.log(first); // "one"
console.log(last); // "four"

//没有获取到值,可以设置默认值
var a, b;
[a=5, b=7] = [1];
console.log(a); // 1
console.log(b); // 7

//获取对象的值
const student = {
  name:'Ming',
  age:'18',
  city:'Shanghai'  
};
const {name,age,city} = student;
console.log(name); // "Ming"
console.log(age); // "18"
console.log(city); // "Shanghai"

运算符

扩展运算符

使用三个点(...),后面跟着一个可迭代的数据结构。

数组是存放元素集合的一个容器,而使用扩展运算符可以将这个容器拆开,只剩下元素集合,可以把这些元素集合放到另外一个数组里面。

// 合并数组
let arr1 = [1, 2, 3, 4]
let arr2 = [11, 12, 13, 14]
let arr3 = [...arr1, 5, 6, 7] // [1, 2, 3, 4, 5, 6, 7]
let arr4 = [...arr1, ...arr2] // [1, 2, 3, 4, 11, 12, 13, 14],代替concat方法
let arr5 = [arr1.concat(arr2)] // [1, 2, 3, 4, 11, 12, 13, 14]
var arr6 = [...arr1] // 数组拷贝,等同于 arr1.slice(),都是浅拷贝
arr6.push(5)
console.log(arr6)//[1, 2, 3, 4, 5]

//将类数组转化为数组
let nodeList = document.querySelectorAll("div")
let arr = [...nodeList]
console.log(arr)

//函数调用时将参数展开
function sum(x, y, z) {
  return x + y + z;
}
const numbers = [1, 2, 3];
console.log(sum.apply(null, numbers));
console.log(sum(...numbers)); // 6

剩余运算符

剩余运算符可以代替arguments对象,箭头函数没有arguments,必须使用剩余运算符才能访问参数集合。

function func1(a, b, c) {
   console.log(arguments[0], arguments[1], arguments[2])
}
func1(1, 2, 3)

// res是形参,表示所有的参数
function func2(...res) {
   console.log(res) // [1, 2, 3]
}
func2(1, 2, 3)

剩余运算符和扩展运算符的区别是,剩余运算符会收集这些集合,放到数组中,扩展运算符是将数组拆分成元素的集合,它们是相反的。

模板字符串

通过${}完成字符串的拼接,将变量放在大括号之中。

var name = 'Your name is ' + first + ' ' + last + '.'
var name = `Your name is ${first} ${last}.`

对象属性简写

当对象的属性和值相同时,可以省略属性名。省略的是属性名而不是值,值必须是变量

const name='Ming',age='18',city='Shanghai';
const student = {
    name:name,
    age:age,
    city:city
};

//简写
const name='Ming',age='18',city='Shanghai';
const student = {
    name,
    age,
    city
};

//与解构赋值一起使用
let bar = () => ({x: 1, y: 2, z: 3}) //bar返回一个对象
let ({x: x, y: y, z: z}) = bar() //解构赋值声明x,y,z变量并赋值
let {x, y, z} = bar() // 简写
console.log(x)
console.log(y)
console.log(z)

//当属性是一个函数时,可以简写
let obj = {
    func: function() {}
}
let obj = {
    func() {} //简写
}
let obj = {
    func: () => {} //箭头函数
}

函数默认值

在函数的参数中设置默认值,在函数参数的区域(括号里面),作为一个单独的块级作用域,拥有let,const方法的特性,比如暂时性死区。

当传入的参数为undefined时才使用函数的默认值,显式传入undefined也会触发使用函数默认值,传入null则不会触发。

function func(a = 1) {
    console.log(a)
}

for of循环

遍历一个可迭代的数据结构并且返回各项的值value,支持break,continue,return,可以和对象解构赋值一起使用。

let arr = [{a: 1}, {a: 2}, {a: 3}]
let obj = []
for ({a: obj.a} of arr) {
    console.log(obj.a) // 1 => 2 => 3
}
//arr每次循环返回一个对象{a: 1}, {a: 2}, {a: 3},经过对象解构 {a: obj.a} = {a: 1},给obj.a赋值

Module

解决代码模块化

  • 静态的,在编译阶段运行,和var以及function一样具有提升效果
  • 使用import关键字导入模块
  • 使用export关键字导出模块,export {<变量>}导出具名的接口,export default导出匿名的接口。
//module.js中导出
let a = 1
let b = 2
export {a}
export default b

//main.js中导入
import {a} form 'module.js'
import b form 'module.js'

export {<变量>}导出的是变量的引用,export default导出的是一个值

import() 是动态加载模块,返回一个Promise,Promise被resolve时的值为输出的模块

import('module.js').then(res => {
    console.log(res)
})

Object.assign

Object.assign方法用于多个对象的合并,属于浅拷贝

let arr = {a: 1}
let obj = Object.assign(arr, {b: 2}, {c: 3})
  • 传入target必须是一个可迭代的对象,如果传入一个基本类型,会转为基本包装类型,如果传入不可迭代的数据,会忽略合并。

  • null,undefined没有基本包装类型,所以传入会报错。

  • 使用等号进行赋值,对象的get(),set()方法会直接执行,不会合并。