ES6

63 阅读8分钟

1. 声明定义遍量

  1. let
let num = 100
  1. const
const num = 100
  1. 重点!!!let,const,var的区别 * let,const不允许出现重复的变量 * let,const没有变量提升,let与const定义的变量不能在定义前使用,也有人叫暂时性死区 // 会报错不会是undefined * let,const定义的变量会受限于块级作用域(就是一个大括号,除了函数之外的大括号,也会受限于函数) js if(true){ var a = 100 var b = 200 console.log(b) // 此时可以打印b的值200,因为在会计作用于使用 const c = 300 console.log(c) // 可以打印c } console.log(a) // 此时会打印a为100 console.log(b) // 此时打印找不到b,没法在块级作用域外使用 console.log(c) // 此时打印找不到c,没法在块级作用域外使用

  2. 重点!!!let,const的区别 * let定义的变量值可以改变,const不能,(let定义变量,const定义常量) js let num = 100 num = 200 console.log(num) // 此时打印结果为200 const num1 = 200 num1 = 300 // 此时会报错,因为const是常量,一旦定义不能改变值 * let定义的变量在定义时可以不给值,const不行,因为const定义的是常量,不能改变他的值 js let num num = 100 const num1 // 此时就会报错

2. 箭头函数

  1. 其实就是对普通函数写法上的一个优化
const fn = function (a, b) {
  console.log(a)
  console.log(b)
}
// 可以使用箭头函数写成
const fn1 = (a, b) => {
  console.log(a)
  console.log(b)
}
  1. 如果箭头函数有一个形参可以省略小括号,注意:必须只有一个形参时才可以省略,如果没有形参或者有多个形参不可以省略
const fn1 = (a) => {
  console.log(a)
}
const fn2 = a => {
  console.log(a)
}
  1. 如果箭头函数需要执行的代码只有一行可以省略大括号,并且自带return
const fn2 = a => {
  console.log(a)
}
const fn3 = a => console.log(a)
// 上下效果一样的

const fn4 = (a,b) => {
  return a + b
}
const fn4 = (a,b) => a + b
// 上下效果一样的
  1. 箭头函数的特殊性 * 箭头函数没有this,箭头函数的this是上下文的this(你的箭头函数写在哪里它的this就决定了,this指向上一级作用域的this) * 箭头函数内部没有arguments对象,arguments对象可以拿到所有传递进来的实参但是不推荐

  2. 参数的默认值 * 注意点:如果箭头函数的参数书写默认值的时候不管有几个形参都必须加上小括号 js const fn = (a = 10, b = 20) => a + b

3. 解构赋值

  1. 解构对象
const obj = {
  name : 'qf001',
  age : 18,
  sex : 'man'
}
const {name, age, sex} = obj // 此时可以拿到name,age,sex的值,前面必须是大括号,后面必须是数组
console.log(name)
console.log(age)
console.log(sex)
  1. 解构数组
const arr = ['qf001', 'qf002', 'qf003'] 
const [a, b, c] = arr // 此时可以拿到里面的每一项,前面必须是中括号,后面必须是数组
console.log(a)
console.log(b)
console.log(c)
  1. 注意点: * {} 是专门解构对象使用的 * [] 是专门解构数组使用的

4. 模板字符串与展开运算符

  1. 模板字符串 * ES5的时候字符串只能是单引号或者双引号包裹的内容,弊端:1. 字符串内不能换行,2. 拼接变量的时候不方便 * ES6的模板字符串可以使用反引号包裹,内部如果需要添加变量使用${要添加的变量名}包裹

  2. 展开运算符 * ES6中新增了一个运算符...(展开运算符)(扩展运算符) * 作用:将一个数组展开,展开后就是数组内的内容 * 在对象上使用,注意:只能合并对象,不能展开对象 js let obj = { name : 1, age : 2, } let obj1 = { name : 2, agr : 3, ...obj // 此时obj1中的name为1,age为2 }

  3. 函数传参

const arr = [100, 200, 300]
const fn = (a, b, c) => console.log(a + b + c)
fn(...arr)

5. Set和Map数据结构

  1. Set: * 类似于数组的东西,也是按照索引方式排列 * 不允许使用索引,并且不允许出现重复的数据 js const oSet = new Set([1, 1, 1, 2, 3, 4, 5, 5, 6, 7, 8, 8, 8, 20]) console.log(oSet) // 此时打印结果是没有重复数据的Set数据 console.log(oSet.size) // 类似于数组.length Set的方法:
    // 添加数据 Set数据名.add(数据)
    
const oSet = new Set([1, 1, 1, 2, 3, 4, 5, 5, 6, 7, 8, 8, 8, 20])
oSet.add(5) // 向末尾添加一个数据
// 判断数据结构中有没有这个数据 oSet.has(数据)
oSet.has(5) // 返回一个布尔值true或者false
// 删除一个数据 Set数据名.delete(数据)
oSet.delete(5)
// 清空数据 Set数据名.clear()
oSet.clear()
// 遍历方法 Set数据名.forEach((value, index, origin) => {})
oSet.forEach((value, index, origin) => {
  console.log(value, index, origin) // 此时打印下标为前一个的属性值也就是value和index是一个
// * 获取size长度:Sap属性名.size
})
```

2. Map * 和Set一样也是ES6中新增的数据结构,也是不支持重复数据,这个东西类似于对象 * Map中的属性名可以是任意类型的 * 语法: js let oMap = new Map( [['a',1],['b',2]] ) * 想要添加数据:Map属性名.set('键', 值) * 想要获取数据:Map属性名.get('键') ,可以获取到键对应的值 * 想要查询数据是否存在:Map属性名.has('键') ,返回一个布尔值 true 或者 false * 想要删除数据:Map属性名.delete('键') * 想要清空数据:Map属性名.clear() * 遍历数据:Map属性名.forEach((value, key, origin) => {console.log(value, key, origin)}) * 获取size长度:Map属性名.size js value :键对应的值 key :键 origin :原数组

6. 对象的简写语法

  1. 当key与value相同时(拼写)
  2. 并且value是一个变量,此时可以省略其中一个不写
  3. key的值是一个函数,并且不是箭头函数,那么可以省略function关键字和冒号不写
let fn = function (a){console.log(a)}
let num = 100
let age = 18
let obj = {
  num,
  age,
  fn(a){console.log(a)}
}

7. 模块化语法

  1. 核心:把我们的JS功能整体拆分成一个独立的模块
  2. 一个JS文件就是一个独立的模块,最后根据业务需求将模块整理起来
  3. 当模块化开发的时候我们需要把多个逻辑写在多个JS文件中,此时每个JS文件都是一个独立的模块作用域
  4. 当前作用域内只能使用自己文件中的变量,能不能使用其他文件中的变量
  5. 导入,导出 * 导入:导入该文件的同时拿到他内部向外暴露的变量 * 导出:一个文件中向外暴露的一些内容
  6. 浏览器对于ES6模块化的要求: * script中必须有一个type = module属性 * 运行的页面必须在服务器上,本地打开的页面不能使用模块化语法
  7. 当前文件目录梳理 * index.html:主体文件,静态内容都在他之中,JS也会依赖这个文件 * index.js:主要用于整合JS代码,换句话说不会写太多JS代码,主要将别的JS代码导入近来 * a/b/c/d/... .js:主要模块功能,一定要导出进来 * 导出语法1 js export default 要导出的数据 // 默认导出为 * 导入语法1 js import 变量 from '要导入的文件名.文件后缀' // 注意:1. 必须书写文件后缀名 2. 这种导入语法必须和这种导出语法对应 * 导出语法2 js export 定义一个变量 = 值 export 定义一个变量 = {变量} * 导入语法2 js import {要导入的变量} form '要导入的文件名.文件后缀' // 注意:此语法在用的时候需要给script标签一个type="module"属性 // 注意:1. 必须书写文件后缀名 2. 这种导入语法必须和这种导出语法对应 3. 导入变量名应该和导出变量名一致

8. this的指向只跟函数的调用有关系,跟函数的书写没关系

9. 手动更改函数this指向的方法

  1. call * 语法:函数名.call(要改变的 this 指向, 要给函数传递的参数1, 要给函数传递的参数1, ...)
var obj = {
  name:'qf001',
  age:18,
}
function fn(a,b){
  console.log(this,a,b)
}
fn() // 此时this指向为window
fn.call(obj) // 将函数内部this指向改变为obj
  1. apply * 此方法跟第一个方法类似,但是语法上有点差别 * 语法:函数.apply(将this指向什么,[传递给函数的参数1,传递给函数的参数2,...]) js var obj = { name:'qf001', age:18, } function fn(a,b){ console.log(this,a,b) } fn() // 此时this指向为window fn.apply(obj,[100,200]) // 将函数内部this指向改变为obj

  2. bind * 该方法和前两个类似,也是附加在函数后调用,可以忽略函数本身的this,并且修改为你传递进去的第一个参数,不同点是你传递进去后不会立即使用,不会调用函数但是会返回一个功能与原本函数相同但是修改了this指向的函数 js var obj = { name:'qf001', age:18, } function fn(a,b){ console.log(this,a,b) } fn() // 此时this指向为window var res = fn.bind(obj) // 将函数内部this指向改变为obj,但是不会理解执行 res(100,200)