ES6超详细学习入门
2021-09-07 21:26:02 4 举报
AI智能生成
ES6语言入门
作者其他创作
大纲/内容
ES6基础
ES6简介
什么是ES6?
ECMAScript6
ECMAScript是语言的标准
ECMA
欧洲计算机制造商协会
标准化组织
历史版本
ES1、2比较原始的版本
ES3
do while、switch、正则等
ES4
废弃了
ES5
forEach、map、filter、Object.create、Object.defineProperty等
ES6 <=> ES2015
具体
语法和API
ES和javascript的关系
javascript=ECMAScript+DOM+BOM
ES6兼容性
主流浏览器的最新版本几乎全部支持ES6
IE老版本不支持的可以用Babel转码
let和const
用来声明变量或常量
let代替var声明变量
变量初始化之后可变
const用来声明常量
常量初始化之后不可变,不可重新赋值
声明和初始化要一起完成,不能分开
为什么需要const
为一旦初始化就不需要改变的值来设计的
const声明的常量允许不重新复赋值的情况下改版它的值,如引用类型。基本类型的数据不能修改
let、const、var区别
重复声明:已经存在的变量或者常量又声明了一边
var允许重复声明
函数的入参也属于已经存在的变量
let、const不允许重复声明
变量提升
var会将变量的声明(仅声明)提升至当前作用域的顶部
let、const不存在变量提升
暂时性死区
只要作用域内存在let、const声明的变量或常量,就自动绑定这个区域,不再收到外部作用域的影响
在当前作用域,所要使用的变量已经存在,不会再访问该作用域以外的同名变量,并且只有在声明变量之后,才可以获取和使用该变量,否则就会报错。
window对象的属性和方法
全局作用域中,使用var声明的变量或者function就会自动变成window对象下的变量和方法,也就是全局变量和方法
let、const不会
块级作用域
var没有块级作用域
for(var i=0; i<3;i++){<br>}<br>console.log(i);
会输出3
let、const有块级作用域
for(let i=0; i<3;i++){<br>}<br>console.log(i);
在for循环外面打印i会报错,因为let的作用域就在for循环里面
作用域链
内层作用域->外层作用域->……->全局作用域
有哪些是块级作用域?
{}
for循环
while循环
do while
if
switch
模板字符串和箭头函数
模板字符串
``
使用反引号
通过${值}注入
简单字符串,使用``和使用'' ""没有什么区别
模板字符串,和其他内容拼接混用的时候,使用模板字符串,可以方便注入
var info2 = `我是${person.name},我今年${person.age}岁了`;
注意事项
模板字符串的换行、空格、缩进等等会保留在输出之中。(怎么写就怎么输出)
输出特殊字符(` \)
使用转义
\`
\\
模板字符串的注入
什么内容可以放在模板字符串中?
常量
变量
对象的属性
调用函数
运算操作
只要最终弄可以得到一个值的,都可以使用${}进行注入
箭头函数
箭头函数结构
()=>{}
参数 => {函数体}
const add = (x, y) => {<br> return x + y;<br>}
可以将普通函数转化为箭头函数
箭头函数的注意事项
单个参数情况
()圆括号可以省略,但是无参数、多个参数不能省略
单行函数体
单行函数体可以同时省略大括号和return
单行对象
按照单行函数体改造,需要在对象的大括号外再加一个小括号,让浏览器不再认为大括号是函数体的大括号
不适用箭头函数的场景
构造函数
需要this指向调用对象的时候
因为箭头函数没有this
需要arguments的时候
箭头函数中没有arguments
this指向问题
全局作用域中的this指向
指向window
一般函数(非箭头函数)中的this指向
规则
只有在调用函数的时候this指向才能确定,不调用的时候不知道指向是谁
this指向和在哪里调用没有关系,只和谁调用有关系
function add(){<br> console(this);<br>};<br><br>add();// 这里调用的add() ,在非严格模式下,undefined 转化为了window 也就是调用了window.add();<br>// 在严格模式下是undefined<br>
箭头函数中的this指向
箭头函数没有自己的this,通过作用域链寻找this的指向
严格模式和非严格模式
为什么使用严格模式?
严格模式消除了JavaScript语法的一些不合理、不严谨之处,减少一些怪异行为。
消除代码运行一些不安全之处,保证代码运行的安全。
提高代码编译效率,增加运行速度。
为未来新版本的JavaScript做好铺垫。
如何使用严格模式?
1、为整个脚本开启严格模式
需要在所有语句之前放一个特定语句"use strict"
<script><br>// 整个脚本都开启严格模式的语法<br>"use strict";<br>let v = "Hi! I'm a strict mode script!";<br></script><br>
2、为函数开启严格模式
把"use strict"声明放在函数体的所有语句之前
function strict() {<br> // 函数级别严格模式语法<br> 'use strict';<br> let sum = 1;<br> let result = 0<br> result += sum <br>}<br>
严格模式和非严格模式的区别?
1、将过失错误转为异常
在非严格模式中,不声明变量表示全局变量
在严格模式中,这种会报异常
2、this指向undefined
在非严格模式中,全局作用域中的函数内部this默认指向window
在严格模式中,全局作用域中的函数内部this默认指向undefined
3、不允许变量重名
非严格模式下,允许重复变量命名
严格模式下,不允许重复变量重名
解构赋值
什么是解构赋值
顾名思义,解析某一数据的解构,将我们想要的东西提取出来,赋值给变量或常量
数组的解构赋值
原理
模式(结构)匹配
赋值左右是相同的结构,都是数组
索引值相同的完成赋值,不取的逗号跳过
例子
const [a,b,c] = [1,2,3];// a 1,b 2,c 3
const [a,,c] = [1,2,3];//a 1 c 3
const [i,[,,j],,k] = [1,[2,3,4],5,6];// 1、4、6
const [m] = [1,[3,4],5];<br>console.log(m);// 1<br>const [,n] = [1,[3,4],5];<br>console.log();// [3,4]
数组解构赋值的默认值
数组解构赋值的默认值的生效条件:<br>只有当一个数组成员严格===undefined的时候,默认值才会生效<br>
var [i1,j1] = [];<br>console.log(i1,j1);//undefined undefined<br><br>var [i2=2,j2=3] = [];<br>console.log(i2,j2);//2 3<br>
// 成员值不是undefined,默认值不会生效<br>var [i3=2,j3=3] = [4,5];<br>console.log(i3,j3);//4 5<br><br>var [i4=2,j4=3] = [4,null];<br>console.log(i4,j4);//4 null<br>// 默认值生效<br>var [i4=2,j4=3] = [4];<br>console.log(i4,j4);//4 3<br>
默认值表达式
如果默认值是表达式,表达式是惰性求值的
// 默认值表达式,惰性求值<br>const fun = ()=>{<br> console.log('我被执行了');<br> return 1;<br>}<br>// 用不到默认值,这个fun函数就不会被执行<br>const [a2=fun()] = [333];<br>console.log(a2);// 333<br><br>// fun被执行的情况<br>const [a3=fun()] = [];<br>console.log(a3);// 执行fun, 1
实际开发中的应用
常见类数组的结构赋值
arguments
NodeList
函数参数的解构赋值
// 使用数组的解构赋值来写<br>// 这里的[x,y]是实参,解构赋值之类对应数组的项<br>const arrArr2 = ([x,y])=>{<br> return x+y;<br>}<br>console.log(arrArr2(arrP));// 7
交换变量的值
let x1=1;<br>let y1=2;<br>[x1,y1] = [y1,x1];<br>console.log(x1,y1);
对象的解构赋值
原理
模式(结构)匹配
属性名相同的完成赋值(可完成取别名)
const person = {username:'张三',age:19,sex:'男'};<br>const {username,age,sex} = person;<br>console.log(username,age,sex);<br>// 后面一个参数是可以取别名<br>const {username:uname,age:itage,sex:sex1} = person;<br>console.log(uname,itage,sex1);
对象解构赋值的注意事项
对象解构赋值的默认值
默认值的生效条件
只有当属性值严格===undefined的时候,默认值才会生效
和数组类似
默认值表达式
如果默认值是表达式,表达式是惰性求值的
和数组类似
将一个已经声明的变量用于解构赋值
整个的赋值需要在圆括号中完成
let x3;<br>//let { x3 } = { x3: 12121212121 };//Identifier 'x3' has already been declared<br>({ x3 } = { x3: 12121212121 });<br>console.log(x3);
可以取到继承的属性
const {toString} = {};<br>console.log(toString);// toString是继承来的方法
对象解构赋值在实际中的应用
其他数据类型的解构赋值
字符串的解构赋值
以数组形式解构赋值
const [a,b] = 'hello';// h e
以对象形式解构赋值
const {0:aa99,1:bb99,4:oo99,length} = 'hello';
数值和布尔类型的解构赋值
只能使用对象形式的解构赋值
会先将等号右边的转化为对象再解构赋值<br>但是得不到自己的值
const {a=1,toString} = true;
undefined和null的解构赋值
由于undefined和null都不能转换为对象,所以无法解构赋值,会报错
对象字面量的增强和函数参数的默认值
对象字面量的增强
属性和方法的简洁表示法
1、键名和变量名或常量名一样的时候,可以只写一个
let name='张三';<br>const person = {<b>name</b>,age:11};
2、方法可以省略冒号和function关键字
const p = {<br> name: '张三',<br> say: function () {<br> console.log('say');<br> },<br> // 属性是方法,可以省略冒号和function关键字<br> <b>speak() </b>{<br> console.log('speak');<br> }<br>}
方括号语法
方括号的用法
方括号也可以运变量传进来用在对象字面量中,将属性名可作为一个变量传进来
const prop = 'sex';<br>const student = {name:'ellie',age:19,[prop]:'男'};
方括号里面可以放什么
只要可以计算求得值的都可以放在方括号中,和${}注入类似
方括号和点语法的区别
点语法是方括号语法的特殊形式
属性名是合法标识符的时候才能使用点语法,其他情况可以使用方括号语法
函数参数的默认值
函数参数的默认值什么?
调用函数的时候,穿了参数就使用所传的参数,如果没有传参数,就使用默认值
const m = (x, y = 1) => x * y;
函数参数默认值的注意事项
默认值的生效条件
不传参数或者参数为undefined,默认值才会生效
默认值是表达式的情况
如果默认值是表达式,表达式是惰性求值
小技巧
从函数参数的右边开始设置默认值
函数参数默认值的应用
当传入很多很多参数的时候,可接收一个对象作为参数
剩余参数和展开运算符
剩余参数
什么是剩余参数
当不知道传入多少参数时,使用...加一个参数名老表示剩余参数
const fun = (a,b,...args)=>{}
剩作为函数参数时,余参数永远是个数组,即使没有值也是个空数组<br>
使用剩余参数的注意事项
箭头函数的剩余参数
箭头函数如果只有一个剩余参数,也不能省略圆括号
使用剩余参数代替arguments
因为箭头函数中没有arguments
const add = (...args)=>{}
剩余参数的位置
只能是最后一个参数,后面不能再有参数了,否则会报错
应用
结合解构赋值使用,必须是最后一个值,<br>解构赋值又可以作为函数参数
const [num,...args] = [1,2,3,4,5,6];
数组
const {x,y,...obj} = {x:1,a:2,y:3,z:4,q:91};
对象,这里就是剩余元素,是一个对象而不是数组了
展开运算符
认识展开运算符
将数组形式转化为参数列表形式
...[数组]
展开运算符和剩余参数的区分
展示运算符:是把数组展示成参数列表,[1,2,3]> 1,2,3
剩余参数:试讲参数列列表转化为数组,1,2,3-> [1,2,3]
例子
// 参数上是剩余参数<br>const add = (...args)=>{<br> console.log(args);<br> // 这里是展开运算符<br> console.log(...args);<br>}<br>add(1,2,3);
[...[1,2,3],4]
结果就是[1,2,3,4]
数组的展开运算符
拷贝数组
var array = [1,2,3,[4]]; <br> const newArr = [...array];
不适用二维数组?
合并数组
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #0000ff;">var</span> <span style="color: #001080;">arr0</span> = [<span style="color: #098658;">1</span>,<span style="color: #098658;">2</span>];</div><div><span style="color: #0000ff;">var</span> <span style="color: #001080;">arr1</span> = [<span style="color: #098658;">3</span>];</div><div><span style="color: #0000ff;">var</span> <span style="color: #001080;">arr2</span> = [<span style="color: #098658;">4</span>,<span style="color: #098658;">5</span>];</div><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">arrA</span> = [...<span style="color: #001080;">arr0</span>,...<span style="color: #001080;">arr1</span>,...<span style="color: #001080;">arr2</span>];<br></div></div><font face="Verdana"><b><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">arrAB</span>= [...<span style="color: #001080;">arr0</span>,2,2,...<span style="color: #001080;">arr1</span>,...<span style="color: #001080;">arr2,1,1,1,1</span>];</b></font><br>
字符串转化为数组
const str = 'hello';<br>const arrrrrrr = [...str];
常见的类数组转化为数组
arguments
[...arguments]
NodeList
[...nodeList]
对象的展开运算符
展开对象
对象不能直接展开,需要放在{}中展开
把属性罗列出来,放在一对大括号中,构成一个新的对象
合并对象
{...person,...student}
前后属性名相同的,后面的覆盖前面的,属性名不同的都保留
{person,student}
{person:{.....},student:{......}}
{...person,student}
{name:'zhangsan',...,student:{......}}
注意事项
空对象的展开
其实没有效果,得到的还是空对象
非对象的展开
如果展开的不是对象,则会将其先转化为对象再展开
数值、undefined、null、布尔等,展开得到的还是空对象
字符串的展开
类数组对象
{...'hello'}
{o:'h',1:'e',........,4:'o'}
在对象中展开一个数组
和在对象中展开一个字符串效果一样
不会再对象中再次展开里面的对象
实际应用
复制对象
疑问:对象中含有对象复制是否有问题?
用户参数和默认参数
const logUser = user => {<br> // 设置一个默认值<br> const defaultParam = { name: 'zhangsan', age: 18, sex: '男' };<br> // 将对象合并,并用传入的参数覆盖默认值<br> let param = { ...defaultParam, ...user };<br> console.log(param);<br><br>}<br>logUser();<br>logUser({name:'张三'});<br>logUser({name:'张三',age:20});<br>logUser({name:'张三',age:20,sex:'女'});
reduce
<b>Set和Map数据结构</b>
Set
Set是什么
Set是一系列无需的、且没有重复值的数据集合
和数组有些相似之处
只能通过new Set() 来创建,不能通过字面量创建
Set没有下标去标识每一个值,所以Set是无序,不能像数组那样通过下标获取到对应的值
Set实例的方法和属性
方法
实例.add();
添加成员,可以连缀
实例.has();
是否包含某成员
实例.delete();
删除某成员,删除不存在的成员也不会报错
实例.clear();
清空
forEach遍历set
// 遍历 set中 value和key代表的一样<br>se.forEach(function (value,key){<br> console.log(value,key);<br>});
按照成员添加的顺序遍历的
const obj = {};<br>// 第二个参数时传入的上下,但是是箭头函数没有this<br>se.forEach((value, key, se) => {<br> console.log(this);// window<br>}, obj);
属性
实例.size
值的个数
Set构造函数的参数
数组
const set = new Set([1, 2, 6, 6, 6, 6, 6, 7, 8]);
字符串
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div> <span style="color: #0000ff;">const</span> <span style="color: #0070c1;">set0</span> = <span style="color: #0000ff;">new</span> <span style="color: #267f99;">Set</span>(<span style="color: #a31515;">'hello'</span>);</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #0070c1;">set0</span>);<span style="color: #008000;">// h e l l o</span></div></div>
arguments、NodeList
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">set1</span> = <span style="color: #0000ff;">new</span> <span style="color: #267f99;">Set</span>(<span style="color: #0000ff;">arguments</span>);</div>
Set
<div style="font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div style="color: rgb(0, 0, 0);"><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">set2</span> = <span style="color: #0000ff;">new</span> <span style="color: #267f99;">Set</span>([<span style="color: #098658;">1</span>,<span style="color: #098658;">2</span>,<span style="color: #098658;">1</span>,<span style="color: #098658;">1</span>,<span style="color: #098658;">1</span>,<span style="color: #098658;">3</span>]);</div><div style=""><span style="color: rgb(0, 0, 255);">const</span><font color="#000000"> </font><span style="color: rgb(0, 112, 193);">set3</span><font color="#000000"> = </font><span style="color: rgb(0, 0, 255);">new</span><font color="#000000"> </font><span style="color: rgb(38, 127, 153);">Set</span><font color="#000000">(</font><span style="color: rgb(0, 112, 193);">set2</span><font color="#000000">);</font><font color="#00ff00">//不是同一个属于复制</font></div></div>
Set的注意事项
判断重复值的方式
Set对重复值的判断基本遵循严格相等===,但对于NaN不一致,Set中NaN等于NaN
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #008000;">// set判断重复值</span></div><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">set4</span> = <span style="color: #0000ff;">new</span> <span style="color: #267f99;">Set</span>([<span style="color: #001080;">NaN</span>,<span style="color: #0000ff;">undefined</span>,<span style="color: #0000ff;">null</span>,<span style="color: #001080;">NaN</span>,<span style="color: #0000ff;">undefined</span>,<span style="color: #0000ff;">null</span>,<span style="color: #098658;">1</span>,<span style="color: #098658;">2</span>,{},{}]);</div><div><span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #0070c1;">set4</span>);<span style="color: #008000;">// NaN,undefined,null,1,2,{},{}// {}和{}不是同一个引用</span></div></div>
什么时候使用Set
数组或字符串去重
不需要通过下标访问,只需要遍历
为了使用Set的方法和属性时
Set在实际开发中的应用
数组去重
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">arr</span> = [<span style="color: #098658;">1</span>,<span style="color: #098658;">2</span>,<span style="color: #098658;">1</span>];</div><div><span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>([...<span style="color: #0000ff;">new</span> <span style="color: #267f99;">Set</span>(<span style="color: #0070c1;">arr</span>)]);</div></div>
Set可以展开
字符串去重
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">s</span> = <span style="color: #a31515;">'abcddddddeeaaa'</span>;</div><div><span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>([...<span style="color: #0000ff;">new</span> <span style="color: #267f99;">Set</span>(<span style="color: #0070c1;">s</span>)].<span style="color: #795e26;">join</span>(<span style="color: #a31515;">''</span>));</div></div>
单词去重
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #0000ff;">let</span> <span style="color: #001080;">str</span> = <span style="color: #a31515;">"study hard and make and progress every day study"</span>;</div><div><span style="color: #0000ff;">let</span> <span style="color: #001080;">arr10</span> = <span style="color: #001080;">str</span>.<span style="color: #795e26;">split</span>(<span style="color: #a31515;">' '</span>);</div><div><span style="color: #0000ff;">let</span> <span style="color: #001080;">arr11</span> = [...<span style="color: #0000ff;">new</span> <span style="color: #267f99;">Set</span>(<span style="color: #001080;">arr10</span>)].<span style="color: #795e26;">join</span>(<span style="color: #a31515;">' '</span>);</div></div>
Map
Map是什么
Map是键值对的集合
和对象有相似之处
Map和对象的区别
对象一般用字符串当做键,Map的键没有限定,引用类型也可以当做键
只能通过new Map(),没有字面量
Map实例的方法和属性
方法
.set();
可以连写,重复的key后面覆盖前面的
.get(key)
get不存在的键结果是undefined
.has(key)
判断key是否存在
.delete(key)
删除一个不存在的key不会报错,返回false
.clear()
清空map
.forEach
属性
.size;
Map构造函数的参数
数组
只能传二维数组,并且要体现出键值对
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">map0</span> = <span style="color: #0000ff;">new</span> <span style="color: #267f99;">Map</span>([</div><div> [<span style="color: #a31515;">'name'</span>,<span style="color: #a31515;">'zhangsan'</span>],[<span style="color: #a31515;">'age'</span>,<span style="color: #098658;">19</span>],[<span style="color: #a31515;">'sex'</span>,<span style="color: #a31515;">'男'</span>]</div><div>]);</div></div>
Set
也只能是键值对形式
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">set9</span> = <span style="color: #0000ff;">new</span> <span style="color: #267f99;">Set</span>([[<span style="color: #a31515;">'name'</span>, <span style="color: #a31515;">'zhangsan'</span>], [<span style="color: #a31515;">'age'</span>, <span style="color: #098658;">19</span>], [<span style="color: #a31515;">'sex'</span>, <span style="color: #a31515;">'男'</span>]]);</div><div><span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #0070c1;">set9</span>);</div><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">map1</span> = <span style="color: #0000ff;">new</span> <span style="color: #267f99;">Map</span>(<span style="color: #0070c1;">set9</span>);</div><div><span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #0070c1;">map1</span>);</div></div>
Map
相当于复制了新的Map<br>但map中值是引用类型的还是原来的引用
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #008000;">//传map</span></div><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">map2</span> = <span style="color: #0000ff;">new</span> <span style="color: #267f99;">Map</span>([</div><div> [<span style="color: #a31515;">'name'</span>, { <span style="color: #001080;">a:</span> <span style="color: #098658;">1</span>, <span style="color: #001080;">b:</span> <span style="color: #098658;">2</span> }], [<span style="color: #a31515;">'age'</span>, <span style="color: #098658;">19</span>], [<span style="color: #a31515;">'sex'</span>, <span style="color: #a31515;">'男'</span>]</div><div>]);</div><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">map3</span> = <span style="color: #0000ff;">new</span> <span style="color: #267f99;">Map</span>(<span style="color: #0070c1;">map2</span>);</div><div><span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #0070c1;">map3</span>);</div><div><span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #0070c1;">map3</span> === <span style="color: #0070c1;">map2</span>);<span style="color: #008000;">// ====false</span></div><div><span style="color: #0000ff;">let</span> <span style="color: #001080;">nnn</span> = <span style="color: #0070c1;">map2</span>.<span style="color: #795e26;">get</span>(<span style="color: #a31515;">'name'</span>);</div><div><span style="color: #001080;">nnn</span>.<span style="color: #001080;">a</span> = <span style="color: #098658;">1000000</span>;</div><div><span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #0070c1;">map3</span>);</div><div><span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #0070c1;">map2</span>.<span style="color: #795e26;">get</span>(<span style="color: #a31515;">'name'</span>) === <span style="color: #0070c1;">map3</span>.<span style="color: #795e26;">get</span>(<span style="color: #a31515;">'name'</span>));<span style="color: #008000;">// true</span></div></div>
Map的注意事项
判断键名是否重复的方式
基本遵循严格相等===,NaN例外,Map中NaN和NaN相等
什么时候使用Map
如果只是使用key->value的形式,或者需要字符串以外的值做键,考虑使用Map。<br>只有模拟现实世界的实体时,才用对象<br>
Map实际开发中的应用
见案例
Iterator遍历器和for…of…循环
Iterator是什么
Iterator是遍历器,用来遍历的
遍历的过程
Symbol.Iterator(可遍历对象的生成方法)-> it (可遍历对象)->it.next() ->it.next()->……->直到done为false
寻找数组的Iterator并使用
const it = [1,2][Symbol.Iterator]();
数组的iterator对象
这里的it就是可遍历对象
Iterator解惑
为什么需要Iterator遍历器?
数组可以使用for循环,forEach等,对象可以用for in。Iterator是一个统一的遍历方式
如何更方便的使用Iterator?
我们不会直接去使用Iterator,已经有封装好的方便的用法,底层是用了Iterator
for……of……
认识for……of……
底层是Iterator
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">arr</span> = [<span style="color: #098658;">0</span>, <span style="color: #098658;">1</span>, <span style="color: #098658;">2</span>, <span style="color: #098658;">3</span>, <span style="color: #098658;">4</span>, <span style="color: #098658;">5</span>];</div><div><span style="color: #008000;">// for……of……底层使用的Iterator</span></div><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">it</span> = <span style="color: #0070c1;">arr</span>[<span style="color: #267f99;">Symbol</span>.<span style="color: #0070c1;">iterator</span>]();</div><div><span style="color: #0000ff;">let</span> <span style="color: #001080;">next</span> = <span style="color: #0070c1;">it</span>.<span style="color: #795e26;">next</span>();</div><div><span style="color: #af00db;">while</span> (!<span style="color: #001080;">next</span>.<span style="color: #001080;">done</span>) {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #001080;">next</span>.<span style="color: #001080;">value</span>);</div><div> <span style="color: #001080;">next</span> = <span style="color: #0070c1;">it</span>.<span style="color: #795e26;">next</span>();</div><div>}</div></div>
只会遍历出done为false时对应的value值
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">arr1</span> = [<span style="color: #098658;">0</span>, <span style="color: #098658;">1</span>, <span style="color: #098658;">2</span>, <span style="color: #098658;">3</span>, <span style="color: #098658;">4</span>, <span style="color: #098658;">5</span>];</div><div><span style="color: #af00db;">for</span> (<span style="color: #0000ff;">const</span> <span style="color: #0070c1;">item</span> <span style="color: #0000ff;">of</span> <span style="color: #0070c1;">arr1</span>) {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #0070c1;">item</span>);</div><div>}</div></div>
与break、continue一起使用
break终止循环
continue跳出本次循环
在for……of中如何取到数组的索引
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">arr2</span> = [<span style="color: #098658;">2</span>, <span style="color: #098658;">3</span>, <span style="color: #098658;">4</span>,<span style="color: #098658;">5</span>];</div><div><span style="color: #af00db;">for</span>(<span style="color: #0000ff;">const</span> <span style="color: #0070c1;">key</span> <span style="color: #0000ff;">of</span> <span style="color: #0070c1;">arr2</span>.<span style="color: #795e26;">keys</span>()){</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #0070c1;">key</span>);</div><div>}</div></div>
keys()得到的是索引的可遍历对象
也可以使用values() 得到值的可遍历对象
在for of中同时取到值和索引
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">arr4</span> = [<span style="color: #098658;">2</span>, <span style="color: #098658;">3</span>, <span style="color: #098658;">4</span>, <span style="color: #098658;">5</span>];</div><div><span style="color: #af00db;">for</span> (<span style="color: #0000ff;">const</span> <span style="color: #0070c1;">entry</span> <span style="color: #0000ff;">of</span> <span style="color: #0070c1;">arr4</span>.<span style="color: #795e26;">entries</span>()) {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #0070c1;">entry</span>);<span style="color: #008000;">// 同时获得下标和值</span></div><div>}</div><div><span style="color: #008000;">// 可以直接解构赋值</span></div><div><span style="color: #af00db;">for</span> (<span style="color: #0000ff;">const</span> [<span style="color: #0070c1;">index</span>,<span style="color: #0070c1;">value</span>] <span style="color: #0000ff;">of</span> <span style="color: #0070c1;">arr4</span>.<span style="color: #795e26;">entries</span>()) {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #001080;">index</span>, <span style="color: #001080;">value</span>);<span style="color: #008000;">// 同时获得下标和值</span><span style="font-size: inherit;"> </span></div><div>}</div></div>
原生可遍历和非原生可遍历
什么是可遍历
只要有Symbol.Iterator方法,并且这个方法可以生成可遍历对象,就是可遍历的
只要可遍历,就可以通过fo……of循环来统一遍历
原生可遍历
数组
字符串
Set
Map
arguments
NodeList
非原生可遍历
一般的对象
【拓展】Symbol详解
一、什么是Symbol
Symbol 是 ES6 中引入的一种新的基本数据类型,用于表示一个独一无二的值。它是 JavaScript 中的第七种数据类型,与 undefined、null、Number(数值)、String(字符串)、Boolean(布尔值)、Object(对象)并列。
<div>const a = Symbol();</div><div>console.log(a); //Symbol()</div><div>console.log(typeof a) // 类型是:Symbol</div><div><br></div>
二、Symbol语法规范
1、基本语法
let a = Symbol();<br>let b = Symbol();<br>console.log(a); //Symbol()<br>console.log(b); //Symbol()<br>console.log(a === b) // false<br>
let a = Symbol("symbol1");<br>let b = Symbol("symbol2");<br>console.log(a); //Symbol("symbol1")<br>console.log(b); //Symbol("symbol2")<br>
可以传入字符串
2、遍历
let s1 = Symbol('a');<br>let s2 = Symbol('b');<br>// 由于 s1 和 s2 是一个变量,而不是字符串,因此需要使用中括号括起来(否则它会被当做字符串使用)<br>let a = {<br> name: "夕山雨",<br> [s1]: 24,<br> [s2]: function(){}<br>}<br>
以 Symbol 类型的变量作为对象属性时,该属性不会出现在 for … in、for … of循环中(后面小节就会讲解for…of循环的)。
3、Symbol.for(),Symbol.keyFor()
(1)Symbol.for():Symbol 提供的一种可以创建相同 Symbol 的机制,<br>就是使用 Symbol.for()方法进行注册<br>
let a = Symbol.for('imooc'); //全局注册了以"imooc"为描述符的 Symbol<br>//由于描述符"imooc"已被注册到全局,因此这里创建的 Symbol 与上面是同一个<br>let b = Symbol.for('imooc'); <br>console.log(a === b) // true<br>
(2)Symbol.keyFor():返回一个全局注册的 Symbol 的描述符
let a = Symbol.for('imooc');<br>let res = Symbol.keyFor(a)<br>console.log(res) // imooc<br>
三、symbol-的作用
<span style="color: rgb(32, 33, 36); font-family: menlo, monospace; font-size: 11px; white-space: pre-wrap;">由于每一个 Symbol 值都是不相等的,这意味着 Symbol 值可以作为标识符,用于对象的属性名,就能保证不会出现同名的属性。<br>这对于一个对象由多个模块构成的情况非常有用,能防止某一个键被不小心改写或覆盖。</span><br>
let s1 = Symbol('s1');<br>let s2 = Symbol('s2')<br>const obj = {<br> age: 16,<br> age: 19,<br> [s1]: 'Hello!',<br> [s2]: 'world'<br>};<br>console.log(obj)<br>
四、常用内置的-symbol-值:symbol.iterator
<span style="color: rgb(32, 33, 36); font-family: menlo, monospace; font-size: 11px; white-space: pre-wrap;">对象的 Symbol.iterator 属性,指向该对象的默认遍历器方法 ,凡是具有[Symbol.iterator]方法的对象都是可遍历的,可以使用 for … of循环依次输出对象的每个属性。</span><br>数组和类数组,以及 ES6 新增的 Map、Set 等都原生部署了该方法,因此它们都可遍历<br>
<span style="color: rgb(32, 33, 36); font-family: menlo, monospace; font-size: 11px; white-space: pre-wrap;">五、Symbol 与基本数据类型转换</span>
<span style="color: rgb(32, 33, 36); font-family: menlo, monospace; font-size: 11px; white-space: pre-wrap;">(1)Symbol 不能转成数字。会报错</span>
<span style="color: rgb(32, 33, 36); font-family: menlo, monospace; font-size: 11px; white-space: pre-wrap;">(2)可以转成布尔值和字符串</span>
<span style="color: rgb(7, 17, 27); font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 16px; white-space: pre; background-color: rgb(251, 253, 255);">let s1 = Symbol('1');<br>console.log(typeof s1) // symbol<br>let str = String(s1)<br>console.log(typeof str) // string<br>let bool = Boolean(s1)<br>console.log(typeof bool) // boolean</span>
使用了Iterator的场合
数组的展开运算符
只要是可遍历的,都可以按照数组的形式运算展开运算符展开,这就是为什么set、map、字符串、arguments、类数组等可以直接展开
数组的解构赋值
只要是可遍历的,都可以按照数组的形式进行解构赋值,这就是为什么set、map、字符串、arguments、类数组等也可以解构赋值
Set、Map的构造函数
for……of
ES6的新增方法
字符串的新增方法
includes()
字符串中是否包含某些字符
第二个参数:开始搜索的位置,不传,默认为0
padStart()和padEnd()
原字符串不会被截掉,补全字符串长度(从头部开始补全、从尾部开始补全)
<div style="font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><font color="#0070c1">'x'</font><span style="color: rgb(0, 0, 0);">.<span style="color: #795e26;">padStart</span>(<span style="color: #098658;">6</span>,<span style="color: #a31515;">'wy'</span>)</span></div>
没投传补全的字符串,会用空格补全
trimStart()和trimEnd()
去除字符串的首尾空格,字符串中间的空格不会去除
replaceAll()
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #a31515;">'aabbcc'</span>.<span style="color: #795e26;">replace</span>(<span style="color: #a31515;">'a'</span>,<span style="color: #a31515;">'x'</span>));<span style="color: #008000;">// 这里只能替换第一个a为x</span></div><div><span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #a31515;">'aabbcc'</span>.<span style="color: #795e26;">replace</span>(<span style="color: #811f3f;">/a/</span><span style="color: #0000ff;">g</span>,<span style="color: #a31515;">'x'</span>));<span style="color: #008000;">// 使用正则替换所有的a</span></div><div><span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #a31515;">'aabbcc'</span>.<span style="color: #795e26;">replaceAll</span>(<span style="color: #a31515;">'a'</span>,<span style="color: #a31515;">'x'</span>));<span style="color: #008000;">//这样可以替换所有的a为x</span></div><div><span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #a31515;">'aabbcc'</span>.<span style="color: #795e26;">replaceAll</span>(<span style="color: #811f3f;">/a/</span><span style="color: #0000ff;">g</span>,<span style="color: #a31515;">'x'</span>));</div><div><span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #a31515;">'aabbcc'</span>.<span style="color: #795e26;">replaceAll</span>(<span style="color: #811f3f;">/a/</span>,<span style="color: #a31515;">'x'</span>));<span style="color: #008000;">//这里会报错,replaceAll里如果是已正则必须带g</span></div></div>
数组的新增方法
includes()
数组中是否含有某个成员
基本遵循严格相等===,但NaN不同,includes中认为NaN相同
第二个参数时起始搜索位置,不传默认为0
Array.form()
把其他数据转化为数组
哪些可以转换为数组
字符串、Set、Map、NodeList、arguments等
拥有length属性的任意对象,只会将键是数字的值转为数组,并且按照数字键的顺序
第二个参数:类似于数组的map()方法,对得到的值做一些处理
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #008000;">// ["h111", "e111", "l111", "l111", "o111"]</span></div><div><span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #267f99;">Array</span>.<span style="color: #795e26;">from</span>(<span style="color: #a31515;">'hello'</span>, <span style="color: #001080;">value</span> <span style="color: #0000ff;">=></span> {</div><div> <span style="color: #af00db;">return</span> <span style="color: #001080;">value</span> + <span style="color: #a31515;">'111'</span>;</div><div>}));</div></div>
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>([<span style="color: #098658;">1</span>, <span style="color: #098658;">2</span>].<span style="color: #795e26;">map</span>(<span style="color: #001080;">value</span> <span style="color: #0000ff;">=></span> <span style="color: #001080;">value</span> * <span style="color: #098658;">2</span>));<span style="color: #008000;">// [2,4]</span></div>
第三个参数:给第二个函数传入this指向
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #008000;">// Array.from()第三个参数</span></div><div><span style="color: #267f99;">Array</span>.<span style="color: #795e26;">from</span>(<span style="color: #a31515;">'hello'</span>, <span style="color: #001080;">value</span> <span style="color: #0000ff;">=></span> {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #0000ff;">this</span>);<span style="color: #008000;">// 因为这里是箭头函数没有this,所以还是window</span></div><div>}, <span style="color: #001080;">document</span>);</div><div><span style="color: #267f99;">Array</span>.<span style="color: #795e26;">from</span>(<span style="color: #a31515;">'hello'</span>, <span style="color: #0000ff;">function</span> () {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #0000ff;">this</span>);<span style="color: #008000;">// document </span></div><div>}, <span style="color: #001080;">document</span>);</div><div><span style="color: #267f99;">Array</span>.<span style="color: #795e26;">from</span>(<span style="color: #a31515;">'hello'</span>, <span style="color: #0000ff;">function</span> () {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #0000ff;">this</span>);<span style="color: #008000;">// {} </span></div><div>}, {});</div><div><span style="color: #267f99;">Array</span>.<span style="color: #795e26;">from</span>(<span style="color: #a31515;">'hello'</span>, <span style="color: #0000ff;">function</span> () {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #0000ff;">this</span>, <span style="color: #0000ff;">this</span>[<span style="color: #098658;">0</span>]);<span style="color: #008000;">// {'0':'1'} , 1</span></div><div>}, { <span style="color: #a31515;">'0'</span><span style="color: #001080;">:</span> <span style="color: #a31515;">'1'</span> });</div></div>
find() 和 findIndex()
找到某个值(找到符合的哪一个立即返回值)、找到某个值对应的索引(找到符合的哪一个立即返回其索引)
第一个参数是回调函数
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #008000;">// 输出3</span></div><div><span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>([<span style="color: #098658;">1</span>, <span style="color: #098658;">2</span>, <span style="color: #098658;">3</span>, <span style="color: #098658;">4</span>].<span style="color: #795e26;">find</span>((<span style="color: #001080;">value</span>, <span style="color: #001080;">index</span>, <span style="color: #001080;">arr</span>) <span style="color: #0000ff;">=></span> {</div><div> <span style="color: #af00db;">return</span> <span style="color: #001080;">value</span> > <span style="color: #098658;">2</span>;</div><div>}));</div></div>
回调函数的参数:值value、索引index、数组自身
第二个参数是this指向
同Array.form()的第三个参数,注意箭头函数没有this
对象的新增方法
Object.assign()
合并对象
将属性直接合并到了第一个参数对应的对象中,返回的就是合并后的对象
为了防止第一个参数被修改,一般将一个空对象作为第一个参数
Object.assign({},o1,o2……,on);
注意事项
如果基本类型作为源对象时(源是指第2个参数或者第n个参数,第一个参数时目标对象)
会将基本数据类型转换为对象,再合并。与对象的展开类似
同名属性覆盖
后面的会覆盖前面的
应用
合并用户参数和默认参数
获取对象键值等
Object.keys()
得到对象的键的数组
Object.values()
得到对象键对应值的数组
Object.entries()
得到一个二维数组,二维数组里面的数组,第一个值是键,第二个值是键对应的值
以上3个和数组遍历中的区别
返回值
对象返回的是数组,数组的返回的是可遍历对象Iterator
调用者
数组是实例方法,对象是构造函数方法
使用for……of遍历对象
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">person</span> = { <span style="color: #001080;">name:</span> <span style="color: #a31515;">'zhangsan'</span>, <span style="color: #001080;">age:</span> <span style="color: #098658;">19</span>, <span style="color: #001080;">sex:</span> <span style="color: #a31515;">'n'</span> };</div><div><span style="color: #af00db;">for</span> (<span style="color: #0000ff;">const</span> <span style="color: #0070c1;">key</span> <span style="color: #0000ff;">of</span> <span style="color: #267f99;">Object</span>.<span style="color: #795e26;">keys</span>(<span style="color: #0070c1;">person</span>)) {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #0070c1;">key</span>);</div><div>}</div><div><span style="color: #af00db;">for</span> (<span style="color: #0000ff;">const</span> <span style="color: #0070c1;">value</span> <span style="color: #0000ff;">of</span> <span style="color: #267f99;">Object</span>.<span style="color: #795e26;">values</span>(<span style="color: #0070c1;">person</span>)) {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #0070c1;">value</span>);</div><div>}</div><div><span style="color: #af00db;">for</span> (<span style="color: #0000ff;">const</span> <span style="color: #0070c1;">item</span> <span style="color: #0000ff;">of</span> <span style="color: #267f99;">Object</span>.<span style="color: #795e26;">entries</span>(<span style="color: #0070c1;">person</span>)) {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #0070c1;">item</span>);</div><div>}</div><div><span style="color: #008000;">// 解构赋值</span></div><div><span style="color: #af00db;">for</span> (<span style="color: #0000ff;">const</span> [<span style="color: #0070c1;">key</span>, <span style="color: #0070c1;">value</span>] <span style="color: #0000ff;">of</span> <span style="color: #267f99;">Object</span>.<span style="color: #795e26;">entries</span>(<span style="color: #0070c1;">person</span>)) {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #001080;">key</span>, <span style="color: #001080;">value</span>);</div><div>}</div></div>
注:不保证顺序
<b>ES6之Promise</b>
初识Promise
什么是Promise?
异步操作的一种解决方案
在没学习Promise之前,是用回调函数来处理的,两者也会配合使用
什么时候使用Promise?
用来解决层层嵌套的回调函数(回调地狱 callback hell)的问题
Promise的基本使用
实例化构造函数生成实例对象
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">p</span> = <span style="color: #0000ff;">new</span> <span style="color: #267f99;">Promise</span>(()<span style="color: #0000ff;">=></span>{});</div>
入参是一个回调函数
Promise的状态
有3种状态
一开始是pendding(未完成),执行resolve,变成fulfilled(resolved),已成功
一开始是pendding(未完成),执行reject,变成rejected,已失败
Promise的状态一旦变化,就不会再改变了
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">p</span> = <span style="color: #0000ff;">new</span> <span style="color: #267f99;">Promise</span>((<span style="color: #001080;">resolve</span>,<span style="color: #001080;">reject</span>)<span style="color: #0000ff;">=></span>{</div><div> <span style="color: #001080;">resolve</span>();</div><div> <span style="color: #001080;">reject</span>();</div><div>});</div></div>
先调用了resolve(),已经是fulfilled状态了,后面再调用reject(),状态不会变了
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">p</span> = <span style="color: #0000ff;">new</span> <span style="color: #267f99;">Promise</span>((<span style="color: #001080;">resolve</span>,<span style="color: #001080;">reject</span>)<span style="color: #0000ff;">=></span>{</div><div><span style="color: rgb(0, 16, 128);"> reject</span>(); <br><span style="color: #001080;"> resolve</span>();<span style="font-size: inherit;"> </span></div><div><span style="color: #001080;"></span></div><div>});</div></div><br>
先调用了reject(),已经是rejected状态了,后面再调用resolve(),状态不会变了
then()方法
入参是两个回调函数,第一个是fulfilled的时候调用的,第二个是rejected时候调用de
resolve()、reject()函数的参数
resolve的参数,就是then第一个回调函数里可以接受的参数,比如reject参数可以是new的一个Error对象
Promise的实例方法
<b>then()</b>
什么时候执行?
当pendding->fulfilled,执行then的第1个回调函数
当pendding->rejected,执行then的第2个回调函数
执行后返回值是什么?
then方法执行之后返回一个新的Promise对象,和原来的Promise对象没有关系
then一般会连写
返回的Promise对象的状态如何改变?
then默认返回的是成功状态的Promise对象
在then回调函数体中,return后面的东西会使用Promise包装一下
向后传值
使用Promise解决回调地狱问题
<b>catch()</b>
一般用then()只处理成功的状态,使用catch()方法可以专门用来处理rejected状态,本质上是then的特例
then(null,err=>{});
catch可以捕获前面的错误,一般总是建议,Promise对象后面要跟catch,这样可以处理Promise内部发生的错误
finally()
也是then的特例
什么时候会执行?
当Promise的状态发生变化的时候,不论如何变化都会执行,不变化不执行
Promise的几个构造方法
Promise.resolve()
本质
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><span style="color: #267f99;">Promise</span>.<span style="color: #795e26;">resolve</span>();</div>
成功状态的一种简写形式
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #0000ff;">new</span> <span style="color: #267f99;">Promise</span>(<span style="color: #001080;">resolve</span><span style="color: #0000ff;">=></span>{</div><div> <span style="color: #001080;">resolve</span>();</div><div>});</div></div>
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><span style="color: #0000ff;">new</span> <span style="color: #267f99;">Promise</span>(<span style="color: #001080;">resolve</span> <span style="color: #0000ff;">=></span> <span style="color: #001080;">resolve</span>())</div>
简写:省略大括号
参数
一般参数
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #267f99;">Promise</span>.<span style="color: #795e26;">resolve</span>(<span style="color: #a31515;">'参数'</span>).<span style="color: #795e26;">then</span>((<span style="color: #001080;">data</span>)<span style="color: #0000ff;">=></span>{</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #001080;">data</span>);<span style="color: #008000;">// 输出上面传入的参数</span></div><div>});</div></div>
Promise对象作为参数
<font color="#000000">当Promise.resolve接收的参数是Promise对象时,什么都不做,直接返回这个对象</font>
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">prom</span> = <span style="color: #0000ff;">new</span> <span style="color: #267f99;">Promise</span>((<span style="color: #001080;">r</span>) <span style="color: #0000ff;">=></span> {</div><div> <span style="color: #795e26;">setTimeout</span>(<span style="color: #001080;">r</span>, <span style="color: #098658;">2000</span>, <span style="color: #a31515;">'我是参数'</span>);</div><div>});</div></div>
以下两种写法是等价的
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #0000ff;"></span></div><div></div><div><span style="color: #267f99;">Promise</span>.<span style="color: #795e26;">resolve</span>(<span style="color: #0070c1;">prom</span>).<span style="color: #795e26;">then</span>((<span style="color: #001080;">data</span>) <span style="color: #0000ff;">=></span> {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #001080;">data</span>);</div><div>});</div></div>
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #0070c1;">prom</span>.<span style="color: #795e26;">then</span>((<span style="color: #001080;">data</span>) <span style="color: #0000ff;">=></span> {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #001080;">data</span>);</div><div>});</div></div>
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #267f99;">Promise</span>.<span style="color: #795e26;">resolve</span>(<span style="color: #0070c1;">prom</span>) === <span style="color: #0070c1;">prom</span>);<span style="color: #008000;">// true</span></div>
Promise实例的resolve()方法,如果是结构的Promise对象,也是根据传入的Promise对象的状态变化来决定then执行哪一个回调
具有then方法的对象<br>(用的不多)
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #008000;">// 具有then方法的对象作为参数</span></div><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">obj</span> = {</div><div> <span style="color: #795e26;">then</span>() {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #a31515;">'我是有then方法的对象'</span>);</div><div> }</div><div>};</div><div><span style="color: #008000;">// 首先传入的obj,会先直接调用一下obj里面的then方法。</span></div><div><span style="color: #008000;">//后面的then里面的两个回调都不会执行,因为调用之后生成的Promise对象是pendding状态</span></div><div><span style="color: #008000;">// console.log(Promise.resolve(obj));// pendding状态</span></div><div><span style="color: #267f99;">Promise</span>.<span style="color: #795e26;">resolve</span>(<span style="color: #0070c1;">obj</span>).<span style="color: #795e26;">then</span>(</div><div> (<span style="color: #001080;">data</span>) <span style="color: #0000ff;">=></span> {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #a31515;">'success-我被调用了'</span>, <span style="color: #001080;">data</span>);</div><div> },</div><div> (<span style="color: #001080;">data</span>) <span style="color: #0000ff;">=></span> {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #a31515;">'error-我被调用了'</span>, <span style="color: #001080;">data</span>);</div><div> }</div><div>);</div></div>
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #008000;">// 具有then方法的对象作为参数</span></div><div><span style="color: #008000;">// 但将then方法写的像Promise对象,两个入参,调用一下第一个,后面跟的then就会执行第一个回调</span></div><div><span style="color: #008000;">// 调用一下第二个函数,后面跟的then就会执行第二个回调</span></div><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">obj1</span> = {</div><div> <span style="color: #795e26;">then</span>(<span style="color: #001080;">r1</span>, <span style="color: #001080;">r2</span>) {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #a31515;">'我是有then方法的对象-obj1'</span>);</div><div> <span style="color: #001080;">r1</span>(<span style="color: #a31515;">'success'</span>);</div><div> <span style="color: #008000;">//r2('error');</span></div><div> }</div><div>};</div><div><span style="color: #008000;">// 首先传入的obj1,会先直接调用一下obj1里面的then方法。</span></div><div><span style="color: #267f99;">Promise</span>.<span style="color: #795e26;">resolve</span>(<span style="color: #0070c1;">obj1</span>).<span style="color: #795e26;">then</span>(</div><div> (<span style="color: #001080;">data</span>) <span style="color: #0000ff;">=></span> {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #a31515;">'success-我被调用了'</span>, <span style="color: #001080;">data</span>);</div><div> },</div><div> (<span style="color: #001080;">data</span>) <span style="color: #0000ff;">=></span> {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #a31515;">'error-我被调用了'</span>, <span style="color: #001080;">data</span>);</div><div> }</div><div>);</div></div>
在then方法中的应用
Promise.reject()
本质
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><span style="color: #267f99;">Promise</span>.<span style="color: #795e26;">reject</span>();</div>
失败状态的一种简写形式
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #0000ff;">new</span> <span style="color: #267f99;">Promise</span>((<span style="color: #001080;">resolve,reject)</span><span style="color: #0000ff;">=></span>{</div><div> <span style="color: #001080;">reject</span>();</div><div>});</div></div>
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><span style="color: #0000ff;">new</span> <span style="color: #267f99;">Promise</span>(<span style="color: rgb(68, 68, 68); font-size: 13px; font-family: 微软雅黑;">(</span><span style="font-size: 13px; font-family: 微软雅黑; color: rgb(0, 16, 128);">resolve,reject)</span> <span style="color: rgb(0, 0, 255);">=></span> <span style="color: rgb(0, 16, 128);">reject</span>())</div>
简写:省略大括号
参数
不管什么参数,都会原封不动的向后传送,作为后续方法的参数
在then方法中的应用
<b>Promise.all()</b><br>
作用
用来关注多个Promise对象的状态的变化
传入多个Promise实例,包装成一个新的Promise实例返回
基本用法
子主题
Promise.all()的状态与传入的Promise实例对象状态有关。<br>所有的状态都变成resolved,最终才是resolved;<br>只要有一个是rejected,最终状态就是rejected<br>
Promise.race()
race就是竞赛的意思
Promise.race()的状态取决于第一个完成的Promise对象,<br>第一个完成的成功了,那最终状态就是成功;<br>第一个失败了,那最终状态就是失败<br>
Promise.allSettled()
Promise.allSettled()与传入的Promise对象的状态无关,永远都是成功的。它只会忠实的记录下每个Promise的表现
Promise.any()
传入的参数是一组Promise实例,那么所有Promise实例都变成rejected状态,返回的Promise才会变成rejected状态<br>参数中只要有一个Promise改变为成功状态,则返回的Promise状态就是成功的状态。<br>只要有一个成功就会终止
<span style="color: rgb(32, 33, 36); font-family: menlo, monospace; font-size: 11px; white-space: pre-wrap;">(1) Promise.all() 会返回一组完成值那样,而Promise.any()只能得到一个成功值(假设至少有一个 promise 完成)。当我们只需要一个 promise 成功,而不关心是哪一个成功时此方法很有用的。</span><br>(2)Promise.race() 总是返回第一个结果值,而Promise.any()返回的是第一个成功的值。这个方法将会忽略掉所有被拒绝的promise,直到第一个 promiee 成功。
使用场景
实际开发中,可能会有这样的需求:一次性加载多张图片,哪一张先加载出来就显示哪一张。那么此时就可以使用Promise.any()方法实现效果。
Promise的注意事项和应用
resolve和reject执行后的代码
如果调用了resolve()或者reject()之后,如果后面还有代码,在return之前的代码是会执行的
建议在resolve()或者reject()前加上return,不再执行后面的代码,后面的代码放在后续的then里执行
Promise.all()、Promise.race()、Promise.allSettled()等参数的问题
参数如果不是Promise对象数组,会将不是Promise对象的数组元素转化为Promise对象
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #008000;">// 如果参数不是Promise对象,会包装成Promise</span></div><div><span style="color: #267f99;">Promise</span>.<span style="color: #795e26;">all</span>([<span style="color: #098658;">1</span>, <span style="color: #a31515;">'woshi'</span>, <span style="color: #098658;">3</span>]).<span style="color: #795e26;">then</span>((<span style="color: #001080;">data</span>) <span style="color: #0000ff;">=></span> {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #001080;">data</span>);</div><div>});</div><div><span style="color: #008000;">//等价于</span></div><div><span style="color: #267f99;">Promise</span>.<span style="color: #795e26;">all</span>([</div><div> <span style="color: #267f99;">Promise</span>.<span style="color: #795e26;">resolve</span>(<span style="color: #098658;">1</span>),</div><div> <span style="color: #267f99;">Promise</span>.<span style="color: #795e26;">resolve</span>(<span style="color: #a31515;">'woshi'</span>),</div><div> <span style="color: #267f99;">Promise</span>.<span style="color: #795e26;">resolve</span>(<span style="color: #098658;">3</span>),</div><div>]).<span style="color: #795e26;">then</span>((<span style="color: #001080;">data</span>) <span style="color: #0000ff;">=></span> {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #001080;">data</span>);</div><div>});</div></div>
不只是数组,任何可遍历的对象都可以传入
Promise.all()、Promise.race()、Promise.allSettled()等的错误处理
错误既可以单独处理,也可以统一处理,错误一旦被处理,就不会在其他地方再处理一遍
【扩展】async/await
什么是async/await
async/await是基于Promise实现的。
async/await使得异步代码看起来像同步代码。
<span style="color: rgb(32, 33, 36); font-family: menlo, monospace; font-size: 11px; white-space: pre-wrap;">以前的方法有</span>回调函数和Promise,,async/await是写异步代码的新方式。
async/await语法规范
async 函数返回一个 Promise 对象,可以使用 then 方法添加回调函数。 <br>当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再接着执行函数体内后面的语句。<br>
<div>const timeout= time => {</div><div> return new Promise(function (resolve, reject) {</div><div> setTimeout(function () {</div><div> resolve();</div><div> }, time);</div><div> })</div><div>};</div><div>const start = async () => {</div><div> // 在这里使用起来就像同步代码那样直观</div><div> console.log('start');</div><div> await timeout(3000);</div><div> console.log('end');</div><div> return "imooc"</div><div>};</div><div>start().then(()=> {</div><div> console.log('test....')</div><div>});</div><div><br></div>
注意事项
<span style="color: rgb(32, 33, 36); font-family: menlo, monospace; font-size: 11px; white-space: pre-wrap;">1、await 命令只能用在 async 函数之中,如果用在普通函数,就会报错。</span>
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #0000ff;">function</span> <span style="color: #795e26;">fn</span>() {</div><div> <span style="color: #af00db;">await</span> <span style="color: #0070c1;">timeout</span>(<span style="color: #098658;">300</span>);<span style="color: #008000;">// 报错, await is only valid in async functions and the top level bodies of modules</span></div><div>};</div><div><span style="color: #795e26;">fn</span>();</div><br><div><span style="color: #008000;">// 可以这样用</span></div><div><span style="color: #0000ff;">async</span> <span style="color: #0000ff;">function</span> <span style="color: #795e26;">fn</span>() {</div><div> <span style="color: #af00db;">await</span> <span style="color: #0070c1;">timeout</span>(<span style="color: #098658;">300</span>);</div><div>}</div><div><span style="color: #795e26;">fn</span>();</div></div>
2、await 后面跟着是一个Promise对象, 会等待Promise返回结果了,再继续执行后面的代码。
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #008000;">//2、await 后面跟着是一个Promise对象, 会等待Promise返回结果了,再继续执行后面的代码。</span></div><div><span style="color: #008000;">//执行下面的代码,控制台等待3秒后,输出imooc,然后才输出后面的console.log语句中的end,如下图所示:</span></div><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">timeout1</span> = <span style="color: #001080;">time</span> <span style="color: #0000ff;">=></span> {</div><div> <span style="color: #af00db;">return</span> <span style="color: #0000ff;">new</span> <span style="color: #267f99;">Promise</span>(<span style="color: #0000ff;">function</span> (<span style="color: #001080;">resolve</span>, <span style="color: #001080;">reject</span>) {</div><div> <span style="color: #795e26;">setTimeout</span>(<span style="color: #0000ff;">function</span> () {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #a31515;">'imooc'</span>);</div><div> <span style="color: #001080;">resolve</span>();</div><br><div> }, <span style="color: #001080;">time</span>);</div><div> })</div><div>};</div><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">start1</span> = <span style="color: #0000ff;">async</span> () <span style="color: #0000ff;">=></span> {</div><div> <span style="color: #af00db;">await</span> <span style="color: #0070c1;">timeout1</span>(<span style="color: #098658;">3000</span>);</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #a31515;">'end'</span>);</div><div>};</div><div><span style="color: #0070c1;">start1</span>();</div></div>
3、await 后面跟着的是一个数值或者字符串等数据类型的值,则直接返回该值
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #008000;">// 3、await 后面跟着的是一个数值或者字符串等数据类型的指,则直接返回该值</span></div><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">num</span> = <span style="color: #098658;">1</span></div><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">str</span> = <span style="color: #a31515;">"imooc"</span>;</div><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">arr</span> = [<span style="color: #098658;">1</span>, <span style="color: #098658;">2</span>];</div><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">start2</span> = <span style="color: #0000ff;">async</span> () <span style="color: #0000ff;">=></span> {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #af00db;">await</span> <span style="color: #0070c1;">num</span>)</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #af00db;">await</span> <span style="color: #0070c1;">str</span>)</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #af00db;">await</span> <span style="color: #0070c1;">arr</span>)</div><div>};</div><div><span style="color: #0070c1;">start2</span>();</div></div>
<span style="color: rgb(32, 33, 36); font-family: menlo, monospace; font-size: 11px; white-space: pre-wrap;">4、await后面跟着的是定时器,不会等待定时器里面的代码执行完,而是直接执行后面的代码,然后再执行定时器中的代码。</span>
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #008000;">//4、await后面跟着的是定时器,不会等待定时器里面的代码执行完,而是直接执行后面的代码,然后再执行定时器中的代码。</span></div><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">start4</span> = <span style="color: #0000ff;">async</span> () <span style="color: #0000ff;">=></span> {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #098658;">1</span>)</div><div> <span style="color: #af00db;">await</span> <span style="color: #795e26;">setTimeout</span>(() <span style="color: #0000ff;">=></span> {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #098658;">2</span>)</div><div> }, <span style="color: #098658;">1000</span>);</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #098658;">3</span>);</div><div>};</div><div><span style="color: #0070c1;">start4</span>();<span style="color: #008000;">// 1 3 2</span></div></div>
错误捕获
可以直接用标准的try catch语法捕捉错误
ES6之Class类
初识class
什么是class
人类:类<br>具体的人:实例/对象
类可以看做事对象的模板,用一个类可以创建出多个不同的对象
JS中的类建立在原型上
class基本用法
实例化时会执行构造方法,所以必须有构造方法<br>但可以不写出来,不写就用默认的构造方法<br>
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #008000;">//实例化时会执行构造方法,所以必须有构造方法,但可以不写出来,不写就用默认的构造方法</span></div><div><span style="color: #0000ff;">class</span> <span style="color: #267f99;">Person</span> {</div><div> <span style="color: #0000ff;">constructor</span>() {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #a31515;">'我是构造方法,实例化时会被调用'</span>);</div><div> }</div><div>}</div><div><span style="color: #008000;">// 实例化</span></div><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">p</span> = <span style="color: #0000ff;">new</span> <span style="color: #267f99;">Person</span>();</div></div>
一般在构造方法中定义属性,不再构造方法中定义方法<br>(因为每次创建一个对象就会创建一个方法,创建出来的方法并不是同一个引用,会浪费大量内存)<br>
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #008000;">//实例化时会执行构造方法,所以必须有构造方法,但可以不写出来,不写就用默认的构造方法</span></div><div><span style="color: #0000ff;">class</span> <span style="color: #267f99;">Person</span> {</div><div> <span style="color: #008000;">// 这里可以传入实例化的参数</span></div><div> <span style="color: #0000ff;">constructor</span>(<span style="color: #001080;">name</span>, <span style="color: #001080;">age</span>, <span style="color: #001080;">sex</span>) {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #a31515;">'我是构造方法,实例化时会被调用'</span>);</div><div> <span style="color: #0000ff;">this</span>.<span style="color: #001080;">name</span> = <span style="color: #001080;">name</span>;</div><div> <span style="color: #0000ff;">this</span>.<span style="color: #001080;">age</span> = <span style="color: #001080;">age</span>;</div><div> <span style="color: #0000ff;">this</span>.<span style="color: #001080;">sex</span> = <span style="color: #001080;">sex</span>;</div><div> }</div><div> <span style="color: #008000;">// 这样写是各实例共享的方法</span></div><div> <span style="color: #795e26;">speak</span>() {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #a31515;">'speak'</span>, <span style="color: #a31515;">'我是'</span> + <span style="color: #0000ff;">this</span>.<span style="color: #001080;">name</span>);</div><div> }</div><div> <span style="color: #795e26;">fun</span>() {</div><div> }</div><div>}</div><div><span style="color: #008000;">// 实例化</span></div><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">zs</span> = <span style="color: #0000ff;">new</span> <span style="color: #267f99;">Person</span>(<span style="color: #a31515;">'zhangsan'</span>, <span style="color: #098658;">18</span>, <span style="color: #a31515;">'男'</span>);</div><div><span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #0070c1;">zs</span>.<span style="color: #001080;">name</span>, <span style="color: #0070c1;">zs</span>.<span style="color: #001080;">age</span>, <span style="color: #0070c1;">zs</span>.<span style="color: #001080;">sex</span>);</div><div><span style="color: #0070c1;">zs</span>.<span style="color: #795e26;">speak</span>();</div></div>
class两种定义形式
声明形式
class Person {<br> <span style="color: #0000ff;">constructor</span>(<span style="color: #001080;">name</span>, <span style="color: #001080;">age</span>, <span style="color: #001080;">sex</span>) {<br> ……<br> }<br>}<br>
表达式形式
将一个匿名的类赋值给一个常量
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">Student</span> = <span style="color: #0000ff;">class</span> {</div><div> <span style="color: #0000ff;">constructor</span>(<span style="color: #001080;">id</span>,<span style="color: #001080;">score</span>){</div><div> }</div><div>}</div></div>
立即执行的class
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #0000ff;">new</span> (<span style="color: #0000ff;">class</span> {</div><div> <span style="color: #0000ff;">constructor</span>() {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #098658;">111</span>);</div><div> }</div><div>})();</div></div>
class与构造函数区别
class的typeof是function
class底层是由构造函数实现的
class中添加的方法(不是在构造方法中添加的)就是在原型上的方法
Class的属性和方法
实例属性
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #008000;">// 实例属性</span></div><div><span style="color: #0000ff;">class</span> <span style="color: #267f99;">Cat</span> {</div><div> <span style="color: #008000;"><b>// 这里添加属性,不需要加this,可以设置一些默认值,赋值好右边可以是方法</b></span></div><div> <span style="color: #001080;">name</span> = <span style="color: #a31515;">'miaomiao'</span>;</div><div> <span style="color: #001080;">age</span> = <span style="color: #098658;">10</span>;</div><div> <span style="color: #001080;">sex</span> = <span style="color: #a31515;">'male'</span>;</div><div> <span style="color: #001080;">say</span> = <span style="color: #0000ff;">function</span> () {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #a31515;">'我是'</span> + <span style="color: #0000ff;">this</span>.<span style="color: #001080;">name</span>);</div><div> }</div><div> <span style="color: #0000ff;">constructor</span>(<span style="color: #001080;">name</span>, <span style="color: #001080;">age</span>) {</div><div> <span style="color: #0000ff;">this</span>.<span style="color: #001080;">name</span> = <span style="color: #001080;">name</span>;</div><div> <span style="color: #0000ff;">this</span>.<span style="color: #001080;">age</span> = <span style="color: #001080;">age</span>;</div><div> }</div><div> <span style="color: #795e26;">speak</span>() {</div><div> <span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #a31515;">'我是'</span> + <span style="color: #0000ff;">this</span>.<span style="color: #001080;">name</span>);</div><div> }</div><div>}</div><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">miao</span> = <span style="color: #0000ff;">new</span> <span style="color: #267f99;">Cat</span>(<span style="color: #a31515;">'miaomiaomiao'</span>, <span style="color: #098658;">5</span>);</div><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">miao1</span> = <span style="color: #0000ff;">new</span> <span style="color: #267f99;">Cat</span>(<span style="color: #a31515;">'miaomiaomiao'</span>, <span style="color: #098658;">5</span>);</div><div><span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #0070c1;">miao</span>.<span style="color: #001080;">name</span>, <span style="color: #0070c1;">miao</span>.<span style="color: #001080;">age</span>, <span style="color: #0070c1;">miao</span>.<span style="color: #001080;">sex</span>);</div><div><span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #0070c1;">miao</span>.<span style="color: #001080;">say</span> === <span style="color: #0070c1;">miao1</span>.<span style="color: #001080;">say</span>);<span style="color: #008000;">// <b>false</b></span></div><div><span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #0070c1;">miao</span>.<span style="color: #795e26;">speak</span> === <span style="color: #0070c1;">miao1</span>.<span style="color: #795e26;">speak</span>);<span style="color: #008000;">// <b>true 这里的方法是同一个</b></span></div></div>
静态方法
静态方法就是类的方法
在class中使用static关键字修饰,<br>可以和实例方法同名不会冲突,<br>直接用类打点调用,不需要实例化<br>
class Person{<br> static say(){<br> }<br>}<br>
Person.say=function (){<br>}
但不是很推荐这种写法
静态方法中的this指向的是类本身,而不是实例化出来的对象
静态方法通常用于为一个应用程序创建工具函数。
静态属性
静态属性就是类的属性,<br>要和实例属性区分开
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #0000ff;">class</span> <span style="color: #267f99;">Dog</span> {</div><div> <span style="color: #008000;"><b>// 不要这么写,目前这个只是提案,有兼容性问题</b></span></div><div> <span style="color: #0000ff;">static</span> <span style="color: #001080;">version</span> = <span style="color: #a31515;">'1.0'</span>;</div><div> <span style="color: #008000;">// 可以使用静态方法的形式</span></div><div> <span style="color: #0000ff;">static</span> <span style="color: #795e26;">getVersion</span>() {</div><div> <span style="color: #af00db;">return</span> <span style="color: #a31515;">'1.0'</span>;</div><div> }</div><div>}</div><div><span style="color: #001080;">console</span>.<span style="color: #795e26;">log</span>(<span style="color: #267f99;">Dog</span>.<span style="color: #795e26;">getVersion</span>());</div></div>
私有属性和方法
为什么需要私有属性和方法
声明的类的属性和方法只能在类内部使用的,称之为私有
一般情况下,类的属性和方法都是公开的
目前没有支持的只能在类内部使用的属性和方法,需要模拟
模拟私有属性和方法
下划线开头表示私有,一种约定。<br>在定义一个方法返回这个属性,类外部通过调用这个方法获取
并不能强制不能再类外访问,还是可以访问的,只是约定俗成的不去访问
江苏有属性和方法移出类
将类的声明写在一个IIFE中,私有属性或方法定义在类外,将类赋值给window;<br>在另一个IIEF中实例化类。<br>
Class的继承
<b>extends</b>
子类继承父类
使用extends会继承父类的:属性、实例方法、静态方法、静态属性等。
<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 16px; line-height: 24px; white-space: pre;"><div><span style="color: #008000;">// 继承</span></div><div><span style="color: #0000ff;">class</span> <span style="color: #267f99;">Programmer</span> <span style="color: #0000ff;">extends</span> <span style="color: #267f99;">Person</span> {</div><div> <span style="color: #0000ff;">constructor</span>(<span style="color: #001080;">name</span>, <span style="color: #001080;">age</span>) {</div><div> <b><span style="color: #0000ff;">super</span>(<span style="color: #001080;">name</span>, <span style="color: #001080;">age</span>);</b></div><div> }</div><div>}</div></div>
子类改写继承的属性或方法
子类中写了和父类同名的方法,会<b>同名覆盖。<br></b>子类中新增的,只有子类有。<br>
super
作为函数调用
代表父类的构造方法,只能用在子类的构造方法中,在其他地方使用会报错。这种情况,在子类中调用super相当调用父类的构造方法
super在子类中,this指向的是子类的实例,而不是父类
作为对象使用
在构造方法中或非静态方法中使用<br>此时super代表父类的原型对象,Parent.prototype<br>
可以在子类中调用父类的方法
通过super调用父类的非静态方法时,方法内部的this指向的是当前子类的实例
定义在父类实例上的方法和属性,使用super在子类中不能访问到
<b>在静态方法中使用</b><br>此时super代表父类本身而不是原型对象也不是实例
可以使用子类调用父类的静态方法
通过super调用父类的静态方法时,方法内部的this指向的是当前子类本身而不是子类实例
注意事项
使用super时,需要显性的指出是作为函数还是作为对象使用,否则会报错
当子类继承父类时,如果不需要通过constructor设置属性和继承父类constructor中的属性,那么就可以不写constructor和super,否则,就必须写上constructor和super。<br>
Class实际开发中的应用
幻灯片
ES6之Module(模块)
初识Module
Module是什么
什么是模块
一个一个的局部作用域的代码块
什么是模块系统
模块系统解决的问题
解决模块化的问题
消除全局变量
管理加载顺序
Module的基本用法
使用Module模块化之前的例子
使用script标签加载标签
一个文件就是一个模块了
只要你会用到import或export,在script标签加载时候,就要加上type="module"
<script src="./js/index.js" <b>type='module'</b>></script>
<script <b>type='module'</b>><br> import './module-0.js';<br></script>
Module如何解决模块化的问题的
Module的导入和导出
认识导出和导入
导出的东西可以被导入(import),并访问到
一个模块没有导出,也可以被导入,被导入的代码都会被执行一遍,多次导入,<font color="#b71c1c">也仅执行一遍</font>
import './js/base.js';
export default 和对应的import
export default导出一个默认值
export default XXXX;<br>import xxxx from './js/xxxxxxx.js';<br>
一个模块只能有一个export default
import和export default对应使用的时候,import可以随便取别名,不一定和export default后的一样
export和对应的import
基本用法
export后面跟声明或语句
export的两种写法
export const name = 'zhangsan';
const name='zhangsan';<br>export <b><font color="#b71c1c">{</font></b>name<b><font color="#b71c1c">}</font></b>;
import的写法
import <b><font color="#b71c1c">{</font></b>name<b><font color="#b71c1c">}</font></b> from './js/xxxxxx.js';
这里的name必须和上面的export后的<font color="#b71c1c">名字一样</font>,不能随意取名
多个导出多个导入
const name = 'zhangsan';<br>const fun = function (){};<br>class Person{}<br>const p = { d: "ddd", e: "eee" };<br>export { name, fun, Person, p };<br>
import { fun, name, Person, p } from './module.js';
可以不按照导出的顺序,只要名字对应上即可
导入导出时起别名
使用as取别名
<div class="mind-clipboard"><span style="color: #af00db;">import</span> { <span style="color: #001080;">func</span> <span style="color: #af00db;">as</span> <span style="color: #001080;">say</span>, <span style="color: #001080;">username</span>, <span style="color: #001080;">Person</span>, <span style="color: #001080;">person</span> } <span style="color: #af00db;">from</span> <span style="color: #a31515;">'./module.js'</span>;</div>
<div><span style="color: #af00db;">export</span> { <span style="color: #0070c1;">name</span> <span style="color: #af00db;">as</span> <span style="color: #0070c1;">username</span>, <span style="color: #795e26;">fun</span> <span style="color: #af00db;">as</span> <span style="color: #795e26;">func</span>, <span style="color: #267f99;">Person</span>, <span style="color: #0070c1;">p</span> <span style="color: #af00db;">as</span> <span style="color: #0070c1;">person</span> };</div>
整体导入
<span style="color: #af00db;">import</span> <span style="color: #0000ff;">*</span> <span style="color: #af00db;">as</span> <span style="color: #001080;">obj</span> <span style="color: #af00db;">from</span> <span style="color: #a31515;">'./module-0.js'</span>;<div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 18px; line-height: 27px; white-space: pre;"><span style="color: #af00db;"></span></div>
使用*号导入整体,使用as取个别名,这种写法也会导入xeport default导出的内容
同时导入
同时导入export以及export default所导出的内容
<span style="color: #af00db;">import</span> age, { <span style="color: #001080;">func</span> <span style="color: #af00db;">as</span> <span style="color: #001080;">say</span>, <span style="color: #001080;">username</span>, <span style="color: #001080;">Person</span>, <span style="color: #001080;">person</span> } <span style="color: #af00db;">from</span> <span style="color: #a31515;">'./module.js'</span>;
前面的age是export defaul所导出的,一定要将这个放在前面,否则报错
Module的注意事项
模块顶层的this指向
在模块中,顶层的this指向undefined
可以利用这个特性,如果script标签没有使用type='module'那就会按照普通模式加载而不是模块化了,可以在js模块中判断,顶层this是否是undefined,如果不是,就要给出提示,按照模块化加载js
import关键字和import() 函数
import命令具有提升效果,会提升到整个模块的头部,率先执行<br>import执行的时候,代码还没有执行。import和export命令,只能用在模块的顶层,不能在代码块中执行<br>
比如不能放在if判断中
import()函数可以实现按条件导入
import()返回的是一个Promise对象,后面可以跟then() catch()等
<div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">PC</span> = <span style="color: #0000ff;">true</span>;</div><div><span style="color: #0000ff;">const</span> <span style="color: #0070c1;">Mobile</span> = <span style="color: #0000ff;">false</span>;</div><div><span style="color: #af00db;">if</span> (<span style="color: #0070c1;">PC</span>) {</div><div> <span style="color: #0000ff;"> import</span>(<span style="color: #a31515;">'./module.js'</span>).<span style="color: #795e26;">then</span>(</div><div> () <span style="color: #0000ff;">=></span> {</div><div> <span style="color: #001080;"> console</span>.<span style="color: #795e26;">log</span>(<span style="color: #a31515;">'加载PC端js成功'</span>);</div><div> },</div><div> ……</div><div> );</div><div>} <span style="color: #af00db;">else</span> <span style="color: #af00db;">if</span> (<span style="color: #0070c1;">Mobile</span>) {</div><div> <span style="color: #0000ff;"> import</span>(<span style="color: #a31515;">'./module-0.js'</span>);</div><div>}</div><div style="color: rgb(0, 0, 0); font-family: Menlo, Monaco, "Courier New", monospace; font-size: 18px; line-height: 27px; white-space: pre;"><div><span style="color: #0000ff;"></span></div><div></div></div>
目前import()只是一个提案,可能存在兼容性问题,后续可以结合webpack使用
导入导出的复合写法
可以从一个模块导入然后再导出给其他模块使用,相当于一个中转站
但复合写法导出的无法在当前模块使用
export { version } from "./base.js";
相当于
import {version} from './base.js';<br>export {version};
Module在实际开发中的应用
将默认值等单独拆出一个模块文件,然后将自己导出给其他模块用
将所有常量可以单独拆出一个模块文件,然后将自己导出给其他模块用
相对独立的功能都可以拆出来,注意this
如何更合适的拆分,需要多练多用
ES6之Babel与Webpack<br>
Babel
Bable是什么
认识Babel
Babel是Javascript的编译器,用来将ES6的代码转换为ES6之前版本的代码(ES3、ES5等)
官网:https://babeljs.io/
在线编译:https://babeljs.io/repl
使用Babel
<b>Babel本身可以编译ES6的大部分代码,比如let、const、箭头函数、类等。<br>但是对于ES6新增的API,如Set、Map、Promise等全局对象,以及定义在全局对向上的方法(如Object.assign\Array.fromd等),都不能直接编译,需要借助其他模块</b>
<b>Babel一般要配合Webapck来编译模块(Module)语法</b>
解释编译结果
Babel的使用方式
推荐CLI和Webpack结合
在命令行工具中使用Babel
Babel使用前的准备工作<br>https://babeljs.io/setup#installation<br>
什么是Node.js和npm
Node.js
Node.js是一个平台或者工具,对应浏览器。在这个平台上使用的语言是Node.js,一种后端的Javascript
后端的Javascript=ECMAScript+IO+FIle+……+等服务端的操作
通俗的,一般将后端的Javascript成为Node.js
npm
node包管理工具
安装Node.js
下载包并安装<br>会同时安装好Node 以及npm
node -v
npm -v
官网:https://nodejs.org/en/
初始化项目
在项目目录中
<b>1、npm init</b>
初始化项目
2、初始化之后,会在项目目录下生成一个package.json
使用npm安装包的时候会将安装的情况记录在这个文件中。<br>比如更换开发环境、更换电脑,不需要将下载的包复制一份,只需要有这个文件就可以了<br>可以再使用一些命令,将安装过的包全部再安装一遍就好了
安装Babel需要的包
npm config set registry https://registry.npm.taobao.org<br>
只执行一遍,切换安装源,从国外切换到国内
测试:npm config get registry
根据官网的提示执行:<br>npm install --save-dev @babel/core @babel/cli<br>
--save-dev是指开发依赖
执行完之后会在刚刚的package.json中增加以下内容
"devDependencies": {<br> "@babel/cli": "^7.15.4",<br> "@babel/core": "^7.15.4"<br> }
指向完成后会在当前项目目录下生成安装包的目录node_modules<br>如果这个包丢失,但package.json文件保留,可以在当前项目目录下执行npm install 可以下载package.json中指定的所有包
可以使用@安装指定版本<br>npm install --save-dev @babel/core<b>@7.11.0</b> @babel/cli<b>@7.10.5</b><br>
使用Babel编译ES6代码
编译的命令
根据官网提示添加
"scripts": {<br> <b>"build": "babel src -d dist",</b><br> },
这里的build就是后面一行命令的一个简写,取名字
src指ES6的代码目录
-d dist => -out-dir dist
输出到dist目录
Babel配置文件
根据官网提示添加
安装Babel的包
npm install @babel/preset-env --save-dev
创建Babel配置文件
为了启用预设,您必须在babel.config.json文件中定义它,如下所示:<br><br>{<br> "presets": ["@babel/preset-env"]<br>}
Webpack<br>https://www.webpackjs.com/<br>
Webpack入门
Webpack是什么
认识Webpack
Webpack是<b>静态模块打包器</b>,当Webpack处理应用程序时,会将所有这些模块打包成一个或多个文件
<b>ES6中的Module语法,就是用webpack来处理</b>
Webpack中的模块是什么?
可以理解为:Webpack可以处理的最小单位
ES6中的Module模块,属于Webpack模块。<br>Webpack还可以处理css/js/图片、图标字体等单位。----都可以称之为Webpack模块
Webpack中静态是指什么?
开发过程中存在于本地的css/js/图片、图标字体等文件,就是静态的
动态的内容(比如图片再服务器端存放),Webpack没法处理,只能处理静态的<br>
Webpack初体验
初始化项目
npm init
安装Webpack需要的包
npm install --save-dev webpack-cli@3.3.12 webpack@4.44.1
配置Webpack
配置文件
webpack.config.js
配置文件内容
"webpack": "webpack --config webpack.config.js"
打包并测试
子主题
<b>Webpack核心概念</b>
<b>entry和output</b>
entry
指定入口文件
单个入口文件
entry: "./src/index.js",
多个入口文件
entry: {<br> main:'./src/index.js',<br> search:'./src/search.js'<br> },
output
指定出口
单入口文件对应的输出
const path = require("path");<br>output: {<br> path: path.resolve(__dirname, "dist"),<br> filename: "bundle.js",<br> },<br>
__diename只当前项目目录,绝对路径
resolve是拼接自己的两个参数
filename,指定输出文件名字
多入口对应的输出
output: {<br> path: path.resolve(__dirname, "dist"),<br> filename: "[name].js",<br> },
中括号[name]就是entry多个入口文件对应的最前面的名字
<b>loader</b>
什么是loader<br>
loader就是让Webpack能够去处理非JS模块。loader被用于转换某些类型的模块
学会从官网查找更多的loader使用配置。官网地址:https://www.webpackjs.com/loaders/
babel-loader
安装babel-loader
npm install --save-dev @babel/core@7.11.0 @babel/preset-env@7.11.0
这俩也是需要安装的,如果已经安装了就不需要了
npm install --save-dev babel-loader@8.1.0
创建babel配置文件
引入core-js模块,用来编译ES6新增的PAI,比如Promise等<br>这样引入编译后的js文件在IE浏览器中测试时能通过的
官网地址:https://babeljs.io/docs/en/babel-polyfill
npm install --save-dev core-js@3.6.5
在我们的源码入口js文件头部增加:<br>import "core-js/stable";<br>
打包测试
npm run ……
<b>plugins</b>
什么是plugins
官网地址:https://www.webpackjs.com/plugins/
loader被用于转换某些类型的模块,而插件可以用于执行范围更广的任务。
插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量
以html-webpack-plugin为例学习
初始化项目
安装html-webpack-plugin插件
npm install --save-dev html-webpack-plugin@4.3.0
单页面-配置html-webpack-plugin插件(webpack配置文件)
// 导入html-webpack-plugin插件<br>const HtmlWebpackPlugin = require("html-webpack-plugin");
plugins: [<br> // 如何使用插件,这里实例化一下上面定义的<br> new HtmlWebpackPlugin({<br> template: "3.html",<br> }),<br> ],
多入口页面-配置html-webpack-plugin插件(webpack配置文件)
entry: {<br> <b>main</b>: "./src/index.js",<br> <b>search</b>: "./src/search.js",<br> },
plugins: [<br> // 多入口文件--实例化多次<br> new HtmlWebpackPlugin({<br> template: "index.html",<br> <b> filename:'index.html', //指定生成出的文件名</b><br> // 指定需要引入的哪个js文件,对应entry里的前面那个名字<br> chunks:['<b>main</b>']<br> }),<br> new HtmlWebpackPlugin({<br> template: "search.html",<br> <b> filename:'search.html',</b><br> chunks:['<b>search</b>']<br> }),<br> <br> ],
Webpack的应用
处理css文件
1、以style标签形式嵌入html页面
需要安装css-loader并配置
npm install --save-dev css-loader@4.1.1
webpack只会处理js文件,js以外的文件借助loader处理
需要安装style-loader并配置
npm install --save-dev style-loader@1.2.1
2、抽取css为单独的文件,html使用link引入
也需要安装css-loader并配置
npm install --save-dev css-loader@4.1.1
webpack只会处理js文件,js以外的文件借助loader处理
需要使用插件mini-css-extract-plugin并配置
npm install --save-dev mini-css-extract-plugin@0.9.0
new MiniCssExtractPlugin({<br> // [name] 表示取entry中的名字,没有默认为main<br> filename: "css/[name].css",<br> }),
使用file-loader处理css中的图片
如果图片是服务器的图片,不需要webpack处理。正常就可以执行
需要安装file-loader并配置
npm install --save-dev file-loader@6.0.0
module: {<br> rules: [<br> // 处理css的loader<br> {<br> test: /\.css$/,<br> // 一个loader是这种写法,多个loader就需要用use<br> // loader:'css-loader'<br><br> // 多个loader,注意顺序,这里会从右往左加载<br> // MiniCssExtractPlugin提供loader,是这种用法<br> use: [MiniCssExtractPlugin.loader, "css-loader"],<br> },<br> <b><font color="#ff0000"> // 处理图片的loader<br> {<br> test:/\.(png|jpg|gif)$/,<br> use:['file-loader']<br> }</font></b><br> ],<br> },
file-loader将图片从源码复制了一份到输出目录,并重新取了名字<br>并修改了css引入图片的路径
module: {<br> rules: [<br> // 处理css的loader<br> {<br> test: /\.css$/,<br> // 一个loader是这种写法,多个loader就需要用use<br> // loader:'css-loader'<br><br> // 多个loader,注意顺序,这里会从右往左加载<br> // MiniCssExtractPlugin提供loader,是这种用法<br> <b><font color="#b71c1c"> // 因为这里处理了css到单独的css文件夹下,导致图片处理的时候找错目录<br> use: [<br> {<br> loader: MiniCssExtractPlugin.loader,<br> options: {<br> // 统一加上../<br> publicPath: "../",<br> },<br> },<br> "css-loader",<br> ],</font></b><br> },<br> // 处理图片的loader<br> {<br> test: /\.(png|jpg|gif)$/,<br> <b><font color="#b71c1c"> use: [<br> {<br> loader: "file-loader",<br> options: {<br> // 将图片统一输出到images目录下,[name].[exp]表示保留图片自己的名字和后缀<br> name: "images/[name].[ext]",<br> },<br> },<br> ],</font></b><br> },<br> ],<br> },
使用html-withimg-loader处理html中的图片
需要安装html-withimg-loader并配置
npm install --save-dev html-withimg-loader@0.1.16
module: {<br> rules: [<br> // 处理css的loader<br> {<br> test: /\.css$/,<br> // 一个loader是这种写法,多个loader就需要用use<br> // loader:'css-loader'<br><br> // 多个loader,注意顺序,这里会从右往左加载<br> // MiniCssExtractPlugin提供loader,是这种用法<br> // 因为这里处理了css到单独的css文件夹下,导致图片处理的时候找错目录<br> use: [<br> {<br> loader: MiniCssExtractPlugin.loader,<br> options: {<br> // 统一加上../<br> publicPath: "../",<br> },<br> },<br> "css-loader",<br> ],<br> },<br> // 处理图片的loader<br> {<br> test: /\.(png|jpg|gif)$/,<br> use: [<br> {<br> loader: "file-loader",<br> options: {<br> // 将图片统一输出到images目录下,[name].[exp]表示保留图片自己的名字和后缀<br> name: "images/[name].[ext]",<br> <b><font color="#b71c1c"> // 处理html中的图片需要file-loader配合使用,这里不开启ES6的module模块,否则<br> // html中img的src就是这样子的:src={"default":"images/0.jpg"}<br> //设置成false就是 src="images/0.jpg"<br> esModule: false,</font></b><br> },<br> },<br> ],<br> },<br> <b><font color="#b71c1c"> // 处理html中的img标签<br> {<br> test: /\.(html|html|shtml)$/,<br> use: [<br> {<br> loader: "html-withimg-loader",<br> },<br> ],<br> },</font></b><br> ],<br> },
使用file-loader处理js中的图片
方式同file-loader处理css图片,只不过是在js中给dom元素img设置src<br>在js中导入图片<br>
import imgUrl from "./images/1.jpg";
使用url-loader处理图片
处理一些base64的图片,功能包含file-loader,后续可以统一使用url-loader
npm install --save-dev url-loader@4.1.0
url-loader是以file-loader为基础的,所以file-loader包也需要下载
配置和file-loader相同,功能相似,可以处理css、js图片,但不能处理html引入的图片。多了一个可以base64编码的功能
//url-loader配置,小于10K的图片都会转成base64的格式<br>limit:10000
使用Webpack-dev-server搭建开发环境
安装webpack-dev-server
npm install --save-dev webpack-dev-server@3.11.0
收藏
0 条评论
下一页
为你推荐
查看更多