ES就ECMAScript,ECMA标准化组织发布的一项脚本语言标准化规范
ES6是一个泛指,泛指ES2015及其之后的版本
let关键字是用来定义变量的
let定义的变量有块级作用域,而用var定义的变量是木有块级作用域,块级作用域就是一对花括号
if (true) { var a = 10 } console.log(a) // 10 if (true) { let a = 10 } console.log(a) // 报错:a is not defined // ------------ for (var i = 0; i < 10; i ++) { ... } console.log(i) // 10 for (let i = 0; i < 10; i ++) { ... } console.log(i) // 报错:i is not defined没有变量提升
console.log(a) // 报错:a is not defined let a = 10暂时性死区(与世隔绝,只认所在的块级作用域)
var num = 10 if (true) { console.log(num) // 报错:ReferenceError: can't access lexical declaration `num' before initialization let num = 100 }不能重复定义
let a = 10 let a = 100 // SyntaxError: redeclaration of let aconst关键字:
有块级作用域不可重复定义没有变量提升也有暂时性死区不可重新给常量赋值(变量在栈内存中的值) 复杂数据类型内部的值可以改 定义时必须赋值var、let、const的区别:
varletconst作用域函数(局部)块级块级是否存在变量提升存在不存在不存在是否可重新赋值可以可以不可以是否可重复定义可以不可以不可以定义时是否必须赋值否否是是否存在暂时性死区否是是全局作用域定义时是否会挂载到window上是否否补充说明:优先用const,因为效率要高一丢丢,如果后续发现需要重新赋值,再来改成let
数组解构赋值:
const arr = [1, 2, 3] const a = arr[0] const b = arr[1] const c = arr[2] // -------- 上面的代码等价于下面的代码 --------- const arr = [1, 2, 3] const [a, b, c] = arr // ------- 如果解构时,个数比数组中的元素多,那么只能解构出对应的数据,解构不成功的是undefined,如下范例: ----- const arr = [1, 2, 3] const [a, b, c, d, e] = arr // a = 1, b = 2, c = 3, d = undefined, e = undefined // ------- 如果解构时,个数比数组中的元素少,那么是可以正常解构的,如下范例: ----- const arr = [1, 2, 3] const [a, b] = arr // a = 1, b = 2对象解构:
const user = { name: 'zs', age: 18, sex: '男' } const name = user.name // user['name'], var key = 'name', user[key] const age = user.age const sex = user.sex // --------- 下面的代码和上面等价 -------- const user = { name: 'zs', age: 18, sex: '男' } const { name, age, sex } = user这里注意:变量名必须和对象中的键名一致,否则解构不出来,如果想要改名字,范例如下:
const user = { name: 'zs', age: 18, sex: '男' } const { name: myName, age: myAge } = user // 可以只解构一部分键值对在函数的形参上也可以使用对象结构,如下:
function sayHi(user) { console.log(`hi, my name is ${user.name}, age is ${user.age}, sex is ${user.sex}`) } const zs = { name: 'zs', age: 18, sex: '男' } sayHi(zs) // ------ 下面的代码和上面等价 function sayHi({ name: myName, age, sex }) { console.log(`hi, my name is ${myName}, age is ${age}, sex is ${sex}`) } const zs = { name: 'zs', age: 18, sex: '男' } sayHi(zs)箭头函数(函数的语法糖)
基本语法:
function fn () {} // 上下代码等价 const fn = () => {}如果函数体只有一句代码,可以省略 return 和 花括号(省略掉后,这句代码的结果会作为函数的返回值):
const fn = (n1, n2) => { return n1 + n2 } // 上下代码等价 const fn = (n1, n2) => n1 + n2 // ------------- const fn = (n1, n2) => { console.log(n1, n2) } // 上下代码唯一的区别就返回值的区别 // 上面的代码返回值是undefined // 下面的代码返回值是console.log函数的返回值 const fn = (n1, n2) => console.log(n1, n2)如果形参只有一个,那么小括号也可以省略(如果没有参数或有多个参数,则小括号不能省)
const fn = (v) => { return v * v } // 上下代码等价 const fn = v => v * v箭头函数中的this指向该箭头函数定义时所在位置的this(最重要),如下代码:
范例1:
const obj = { name: '张三'} function fn () { console.log(this) // { name: '张三'} return () => { console.log(this) // { name: '张三'} } } const resFn = fn.call(obj); resFn();范例2:
var age = '100岁' const obj = { name: 'zs', age: 18, sayHi: () => { console.log(this.age) // 100岁 } } obj.sayHi()箭头函数木有arguments变量(是一个伪数组),我们可以用剩余参数来代替(是一个真正的数组),并且效果更好:
const sum = (...args) => { let total = 0 args.forEach((v) => { total += v }) return total } sum(1, 2) sum(1, 2, 3, 4, 5)补充说明:所谓伪数组就意味着不能调用数组相关的API方法,如:forEach、some、push…
剩余参数和解构配合使用:
数组:
const arr = ['red', 'green', 'blue', 'yellow', 'white'] const [s1, ...s2] = arr // const [...s1, s2] = arr // 注意:这是会报错的,剩余参数只能写在最后 console.log(s1) // 'red' console.log(s2) // ['green', 'blue', 'yellow', 'white']对象:
const obj = { name: 'zs', age: 18, sex: '男' } const { name, ...newObj } = obj console.log(name) // 'zs' console.log(newObj) // { age: 18, sex: '男' }扩展运算符
可以将数组中的元素展开成参数序列,如下范例:
const arr = [1, 2, 3] // ...arr // 1, 2, 3 console.log(...arr) // console.log(1, 2, 3) // ----------------------- fn(...arr) // fn(1, 2, 3) const newArr = [0, ...arr, 4, 5, 6] // const newArr = [0, 1, 2, 3, 4, 5, 6] // -------------- const newArr = [] arr.forEach(v => { newArr.push(v) }) // 上下代码等价 const newArr = [...arr]可以将对象中的键值对展开成键值对序列,如下范例:
var obj = { name: 'zs', age: 18 } // ...obj // name: 'zs', age: 18 var newObj = { id: 1, ...obj, sex: '男' } // var newObj = { id: 1, name: 'zs', age: 18, sex: '男' }注意:扩展运算符只能将带有Symbol.iterator属性的伪数组转换成真正的数组
静态方法:直接用构造函数调用的方法
动态方法:用实例调用的方法
Array.from可以把一个伪数组转换成真正的数组,不需要有Symbol.iterator属性
数组实例扩展的方法:
find:找数组中第一个符合条件的元素并返回,内部有循环机制,只要return true,则返回当前循环项,立即终止循环
const arr = [ { id: 1, name: 'zs' }, { id: 2, name: 'ls' } ] const obj = arr.find((v, i) => { /* if (v.id === 2) { return true } */ return v.id === 2 }) // obj = { id: 2, name: 'ls' }findIndex:和find差不多,只不过返回的索引,不是元素
const arr = [10, 20, 50] const index = arr.findIndex(v => v > 15) console.log(index) // 1includes:看数组中是否包含某个元素,返回值是布尔型,true:包含,false:不包含
const arr = ['a', 'b', 'c'] const result1 = arr.includes('b') console.log(result1) // true const result2 = arr.includes('e') console.log(result2) // false如果传递一个函数,那么是找数组中是否包含这个函数,内部并没有循环机制
如果是复杂数据类型,那么找的是内存地址,如下范例:
const obj = { name: 'zs' } const arr = ['a', 'b', 'c', obj] const result1 = arr.includes(obj) // true const result2 = arr.includes({ name: 'zs' }) // false模板字符串:字符串的语法糖
可以写一些简单JS表达式(包括:变量、函数、算数运算、逻辑运算、三元表达式)通过${ 表达式 }可以换行字符串实例方法扩展:
str.startsWith(prefixStr):判断str这个字符串是否以prefixStr开头,类似:/^prefixStr/.test(str)str.endsWith(suffixStr):判断str这个字符串是否以suffixStr结尾,类似:/suffixStr$/.test(str)str.repeat(n):可以将str这个字符串重复n次并返回Set数据结构:ES6新增的数据结构,类似数组,但是内部不会有重复的元素(值、内存地址),并且是一个无序的数据结构,木有索引号
可以通过构造函数来创建Set数据结构的实例:new Set()或new Set([ 1, 2, 3 ])
可以通过size属性获取Set数据结构实例的长度
实例方法:
add:添加,返回值是数据结构本身,可以链式调用delete:删除,返回值是布尔值,true:删除成功,false:删除失败has:是否存在,返回值是布尔值,true:存在,false:不存在clear:清空,木有返回值forEach:遍历元素,类似数组,但是木有索引补充说明,我们可以先将其转换成数组([...someSet]),再来调用数组上强大的API方法操作数据