JS第五天
一、ES6相关概念
1、什么是ES6
ES 的全称是 ECMAScript ,从2015年6月开始每年都会更新一下,统称为ES6
2、使用ES6的目的
- 变量提升特性增加了程序运行时的不可预测性
- 语法过于松散,实现相同的功能,不同的人可能会写出不同的代码
二、ES6新增语法
1、let (★★★)
1.1 作用:
用来声明一个有块级作用域的变量,使用方法和 var 一样
1.2 let 定义变量的特点:
只在声明时的块或子块中可用
不存在变量提升,只能先声明再使用
存在“暂存死区”
同一作用域下不能重复声明同一变量
声明的变量不会挂载在 window 对象上
1.3 暂时性死区的本质
只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
1 2 3 4 5 6
| var bar = 20; if (true) { console.log(bar); let bar = 10; }
|
1.4经典面试题:
1 2 3 4 5 6 7 8
| let arr = []; for (let i = 0; i < 2; i++) { arr[i] = function() { console.log(i) } } arr[0](); arr[1]();
|
2、const关键字
2.1const 作用
用来声明一个有块级作用域的常量(内存地址不能变化的量)
2.2const 定义常量的特点
声明常量时必须要初始化值
同样具有块级作用域和“暂存死区”
赋值为简单数据类型时,不能直接修改值
赋值为复杂数据类型时,可以修改对象内部的属性和方法
1 2 3 4 5 6
| const data = { a: 1, b: 2 }; data.a = 10
|
2.3、let、const、var 的区别

3、解构赋值
3.1解构赋值(强大)
可以从数组或对象中,把值取出来,再赋值给对应的变量
3.2对数组进行解构
let [a, b, …] = 数组
使用变量名和对应位置的数组元素一一匹配,匹配成功就把元素赋值给变量
1 2 3 4 5 6 7 8 9 10 11 12
| const arr2 = [4]; let [aa, bb] = arr2; console.log(aa, bb); let [, a1, b1] = arr; console.log(a1, b1); let num1 = 10; let num2 = 20; [num1, num2] = [num2, num1]; console.log(num1, num2);
|
3.3对对象进行解构
let {prop1, prop2, …} = 对象
使用变量名和对象中的属性名进行一一匹配,匹配成功就把对象的属性值赋值给变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| let obj = { name: '张三', age: 18, height: '175cm', weight: '65kg' } let { sex } = obj; console.log(sex); let { weight, name, age } = obj; console.log(name, age, weight);
|
这里冒号左边的name只用来进行属性名匹配, 冒号右边才是真正赋值的变量
1 2 3 4 5 6 7 8
| let obj = { name: '张三', age: 18, height: '175cm', weight: '65kg' } let {name: name2,height: height1} = obj; console.log(name2, height1);
|
1 2 3 4 5 6 7 8 9 10
| let data = { id: 1, name: '家电', goods: { id: 3, name: 'TV' } } let { goods: {name,id}} = data; console.log(name, id);
|
4、箭头函数
4.1结构(极其简洁)
() => {} ;
4.2 箭头函数的特点
一般不会单独使用, 可以当做匿名函数进行赋值 \ 传参 \ 返回值
如果函数体只有一行代码,并代码执行结果就是返回值, 可以同时省略大括号和 return
如果形参只有一个, 可以省略小括号
内部没有 arguments 这个内置对象
1 2 3 4 5 6 7 8 9 10 11 12
| var arr1 = [1, 2, 3, 4, 5] arr1.forEach(item => console.log(item)) console.log('----------------------'); var arr1 = [1, 2, 3, 4, 5, 6, 7] var newArr = arr1.filter(item => { console.log(item); return item % 2 != 0; }) console.log(newArr);
|
4.3 箭头函数中this指向问题
(★★★) 箭头函数没有自己的 this, 它里面的 this 指向箭头函数所处位置的 this
1 2 3 4 5 6 7 8 9 10 11
| const obj = { name: '张三' } function fn() { console.log(this) return () => { console.log(this) } } const resFn = fn.call(obj) resFn()
|
(★★★)4.4this 情况讨论
(1) 非函数中的 this 指向 window
(2) es5 中函数的 this 指向函数的调用者
(3) call, apply, bind 这三种手动改变 this 的情况特殊对待, this 指向传递的第一个参数
(4) es6 中的箭头函数没有自己的 this, 指向所处位置的 this
5、剩余参数
5.1 剩余参数语法(…变量名)
允许我们将剩下的所有参数表示为一个数组
1 2 3 4 5 6 7 8
| const getSum = (...rest) => { console.log(rest); let sum = 0; rest.forEach(item => sum += item) console.log(sum); } getSum(1, 25, 25, 49)
|
5.2剩余参数和解构配合使用
1 2 3 4
| const arr = ['red', 'orange', 'yellow', 'green', 'black'] let [a, b, ...c] = arr; console.log(a, b); console.log(c);
|
把对象剩下的属性组成一个新对象
使用剩余参数快速实现浅拷贝
1 2 3 4 5 6 7 8 9 10 11
| const obj = { name: '小明', age: 12, height: '170cm', weight: '135kg', } let { ...obj2} = obj; console.log(obj2);
obj2.name = '小李'; console.log(obj2);
|
三、ES6 的内置对象扩展
1、 拓展运算符(展开语法 或 spred运算符)
…对象名 或 …数组名
作用:把数组或对象转为用逗号分隔的参数形式
使用拓展运算符也可以快速完成浅拷贝
1 2
| const arr2 = [...arr1]; console.log(arr2);
|
2、拓展运算符的应用
2.1用来合并数组
- concat方法
- push方法(直接将最后的合并结果赋值给前者)
- 直接利用拓展运算符
1 2 3 4 5 6 7 8 9 10 11
| const arr1 = [1, 2, 3] const arr2 = [4, 5, 6] const res1 = arr1.concat(arr2); console.log(res1); const res2 = [...arr1, ...arr2] console.log(res2);
|
2.2求数组中的最大值
1 2 3
| const arr3 = [5, 4, 3, 2, 1] const res3 = Math.max(...arr3); console.log(res3);
|
2.3拓展对象
1 2 3 4 5 6 7 8 9 10 11
| const obj = { name: 'Jhon', age: 18, color: 'red' } const obj1 = { weight: '120kg', height: 180, color: 'blue' }; console.log({...obj, ...obj1 });
|
2.4拓展字符串
1 2
| const str = 'hello'; console.log(...str);
|
2.5使用拓展运算符拓展字符串和伪数组
结果:为数组,也可以使用forEach进行遍历
3、模板字符串
- ES6新增的创建字符串的方式,使用反引号定义
- 使用 ${变量名或表达式} 代替原来的 ‘引引加加’
- 模板字符串支持换行
- 在模板字符串中可以放任意的表达式 (如三元表达式, 函数调用, 逻辑运算符, +-*/…)
1 2 3 4
| const foo = () => 'abc'; let str3 = `hello${false?'abc':'ABC'} ${foo()}`; console.log(str3);
|
4、构造函数方法Array.from()
1 2 3 4 5 6 7
| const obj = { 0: 'a', 1: 'b', length: 2 } const arr = Array.from(obj); console.log(arr);
|
- (了解)第二个可选参数 fn 用于对转化后的数组进行遍历修改
1 2 3 4 5
| const arr2 = Array.from(obj, function(item) { console.log(item); return item + '1'; }) console.log(arr2);
|
4.1.实例方法:find()
- 用于查找数组中符合条件的第一个元素
- 返回值: 找到就返回这个元素, 没有找到则返回 undefined
1 2 3 4 5
| const arr = [5, 12, 8, 13, 44] console.log(arr.indexOf(8)); const res = arr.find((item, index) => item > 10); console.log(res);
|
4.2 findIndex() 方法
- 用于查找数组中符合条件的第一个元素的索引
- 返回值: 找到就返回当前元素的所以, 没有找到始终返回 -1
1 2 3 4
| const arr = [5, 12, 8, 130, 44] const res = arr.findIndex((item, index) => item > 10); console.log(res);
|
4.3includes(固定值) 方法
- 判断数组是否包含给定的值
- 返回值: 如果包含则返回 true,否则返回 false
1 2 3 4
| const arr = [5, 12, 8, 130, 44] console.log(arr.includes(44)); console.log(arr.indexOf(8) !== -1);
|
注意: 和其他查找方法的区别 ==> includes 只能接受一个固定值,不能接受一个函数
4.4map() 方法
- 基于原数组去创建一个新数组,不影响原数组
- 返回值: 新数组
1 2 3 4
| const arr2 = [2, 4, 6, 8, 10]; const res = arr2.map(item => item / 2); console.log(res); console.log(arr2);
|
4.5 startsWith() 方法
判断字符串是否以某些字符开头,返回 Boolean
1 2
| const str = 'hello wrold'; console.log(str.startsWith('hello'));
|
4.6 endsWith() 方法:
判断字符串是否以某些字符结尾,返回 Boolean
1 2
| const str = 'hello wrold'; console.log(str.endsWith('ld'));
|
4.7 repeat(n) 方法
用于将某个字符串重复 n 次, 返回重复后的新字符串
1 2 3
| let str = '123' str = str.repeat(10); console.log(str);
|
5、Set 数据结构(★★)
它类似于数组,但所有的元素都是唯一的,没有重复值
5.1 语法
new Set(数组)
1 2 3
| const set = new Set([1, 2, 3, 4, 1, 2, 3, 4]); console.log(set); console.log(set.size);
|
5.2 实例方法
- add(value):添加某个值,返回 Set 结构本身
- delete(value):删除某个值,返回一个布尔值,表示删除是否成功
- has(value):返回一个布尔值,表示该值是否为 Set 的成员
- clear():清除所有成员,没有返回值
1 2 3 4 5 6
| const s = new Set(); s.add(1).add(2).add(3); s.delete(2) s.has(1) s.clear()
|
- 案例:利用 set 数据类型的不重复性进行数组去重
1 2 3 4
| const arr = [1, 2, 3, 4, 3, 2, 1]; const set2 = new Set(arr); console.log([...set2]);
|
5.3总结: 数组去重的方法
(1) 建立一个新数组, 遍历数组, indexOf去判断元素是否存在
(2) filter(fn)
(3)原生for循环进行双重遍历,splice(i,1)
(4)[…new Set(arr)]
5.3 遍历
- forEach() 方法遍历 set 数据中的每个元素
- for…of 方法遍历任何可迭代的数据( Set, 数组, Map, 字符串)
1 2 3 4 5 6 7 8 9
| const mySet = new Set([2, 4, 5, 7]);
mySet.forEach(item => console.log(item));
for (let item of mySet) { console.log(item); }
|
注意: 对象不支持 for..of 方法
1 2 3 4 5 6 7 8 9
| const obj = { a: 1, b: 2, c: 3 } for (let item of Object.keys(obj)) { console.log(item); console.log(obj[item]); }
|