ES6超详细学习入门
2021-09-07 21:26:02 4 举报
AI智能生成
登录查看完整内容
ES6语言入门
作者其他创作
大纲/内容
ECMAScript6
欧洲计算机制造商协会
标准化组织
ECMA
ES1、2比较原始的版本
do while、switch、正则等
ES3
废弃了
ES4
forEach、map、filter、Object.create、Object.defineProperty等
ES5
ES6 <=> ES2015
历史版本
ECMAScript是语言的标准
语法和API
具体
什么是ES6?
javascript=ECMAScript+DOM+BOM
ES和javascript的关系
主流浏览器的最新版本几乎全部支持ES6
IE老版本不支持的可以用Babel转码
ES6兼容性
ES6简介
用来声明变量或常量
变量初始化之后可变
let代替var声明变量
声明和初始化要一起完成,不能分开
常量初始化之后不可变,不可重新赋值
为一旦初始化就不需要改变的值来设计的
为什么需要const
const声明的常量允许不重新复赋值的情况下改版它的值,如引用类型。基本类型的数据不能修改
const用来声明常量
函数的入参也属于已经存在的变量
var允许重复声明
let、const不允许重复声明
重复声明:已经存在的变量或者常量又声明了一边
var会将变量的声明(仅声明)提升至当前作用域的顶部
let、const不存在变量提升
变量提升
只要作用域内存在let、const声明的变量或常量,就自动绑定这个区域,不再收到外部作用域的影响
在当前作用域,所要使用的变量已经存在,不会再访问该作用域以外的同名变量,并且只有在声明变量之后,才可以获取和使用该变量,否则就会报错。
暂时性死区
全局作用域中,使用var声明的变量或者function就会自动变成window对象下的变量和方法,也就是全局变量和方法
let、const不会
window对象的属性和方法
会输出3
for(var i=0; i<3;i++){}console.log(i);
外框
var没有块级作用域
在for循环外面打印i会报错,因为let的作用域就在for循环里面
for(let i=0; i<3;i++){}console.log(i);
内层作用域->外层作用域->……->全局作用域
作用域链
{}
for循环
while循环
do while
if
switch
有哪些是块级作用域?
let、const有块级作用域
块级作用域
let、const、var区别
let和const
使用反引号
通过${值}注入
``
简单字符串,使用``和使用'' \"\"没有什么区别
模板字符串,和其他内容拼接混用的时候,使用模板字符串,可以方便注入
模板字符串的换行、空格、缩进等等会保留在输出之中。(怎么写就怎么输出)
\\`
\\\\
使用转义
输出特殊字符(` \\)
常量
变量
对象的属性
调用函数
运算操作
什么内容可以放在模板字符串中?
只要最终弄可以得到一个值的,都可以使用${}进行注入
模板字符串的注入
注意事项
模板字符串
参数 => {函数体}
()=>{}
可以将普通函数转化为箭头函数
箭头函数结构
()圆括号可以省略,但是无参数、多个参数不能省略
单个参数情况
单行函数体可以同时省略大括号和return
单行函数体
按照单行函数体改造,需要在对象的大括号外再加一个小括号,让浏览器不再认为大括号是函数体的大括号
单行对象
箭头函数的注意事项
构造函数
因为箭头函数没有this
需要this指向调用对象的时候
箭头函数中没有arguments
需要arguments的时候
不适用箭头函数的场景
箭头函数
指向window
全局作用域中的this指向
只有在调用函数的时候this指向才能确定,不调用的时候不知道指向是谁
this指向和在哪里调用没有关系,只和谁调用有关系
规则
function add(){ console(this);};add();// 这里调用的add() ,在非严格模式下,undefined 转化为了window 也就是调用了window.add();// 在严格模式下是undefined
一般函数(非箭头函数)中的this指向
箭头函数没有自己的this,通过作用域链寻找this的指向
箭头函数中的this指向
this指向问题
严格模式消除了JavaScript语法的一些不合理、不严谨之处,减少一些怪异行为。
消除代码运行一些不安全之处,保证代码运行的安全。
提高代码编译效率,增加运行速度。
为未来新版本的JavaScript做好铺垫。
为什么使用严格模式?
<script>// 整个脚本都开启严格模式的语法\"use strict\";let v = \"Hi! I'm a strict mode script!\";</script>
需要在所有语句之前放一个特定语句\"use strict\"
1、为整个脚本开启严格模式
function strict() { // 函数级别严格模式语法 'use strict'; let sum = 1; let result = 0 result += sum }
把\"use strict\"声明放在函数体的所有语句之前
2、为函数开启严格模式
如何使用严格模式?
在非严格模式中,不声明变量表示全局变量
在严格模式中,这种会报异常
1、将过失错误转为异常
在非严格模式中,全局作用域中的函数内部this默认指向window
在严格模式中,全局作用域中的函数内部this默认指向undefined
2、this指向undefined
非严格模式下,允许重复变量命名
严格模式下,不允许重复变量重名
3、不允许变量重名
严格模式和非严格模式的区别?
严格模式和非严格模式
模板字符串和箭头函数
顾名思义,解析某一数据的解构,将我们想要的东西提取出来,赋值给变量或常量
什么是解构赋值
赋值左右是相同的结构,都是数组
模式(结构)匹配
索引值相同的完成赋值,不取的逗号跳过
原理
例子
数组解构赋值的默认值的生效条件:只有当一个数组成员严格===undefined的时候,默认值才会生效
// 默认值表达式,惰性求值const fun = ()=>{ console.log('我被执行了'); return 1;}// 用不到默认值,这个fun函数就不会被执行const [a2=fun()] = [333];console.log(a2);// 333// fun被执行的情况const [a3=fun()] = [];console.log(a3);// 执行fun, 1
如果默认值是表达式,表达式是惰性求值的
默认值表达式
数组解构赋值的默认值
arguments
NodeList
常见类数组的结构赋值
函数参数的解构赋值
交换变量的值
实际开发中的应用
数组的解构赋值
属性名相同的完成赋值(可完成取别名)
和数组类似
只有当属性值严格===undefined的时候,默认值才会生效
默认值的生效条件
对象解构赋值的默认值
let x3;//let { x3 } = { x3: 12121212121 };//Identifier 'x3' has already been declared({ x3 } = { x3: 12121212121 });console.log(x3);
整个的赋值需要在圆括号中完成
将一个已经声明的变量用于解构赋值
const {toString} = {};console.log(toString);// toString是继承来的方法
可以取到继承的属性
对象解构赋值的注意事项
对象解构赋值在实际中的应用
对象的解构赋值
以数组形式解构赋值
以对象形式解构赋值
字符串的解构赋值
会先将等号右边的转化为对象再解构赋值但是得不到自己的值
只能使用对象形式的解构赋值
数值和布尔类型的解构赋值
由于undefined和null都不能转换为对象,所以无法解构赋值,会报错
undefined和null的解构赋值
其他数据类型的解构赋值
解构赋值
1、键名和变量名或常量名一样的时候,可以只写一个
2、方法可以省略冒号和function关键字
属性和方法的简洁表示法
方括号也可以运变量传进来用在对象字面量中,将属性名可作为一个变量传进来
方括号的用法
只要可以计算求得值的都可以放在方括号中,和${}注入类似
方括号里面可以放什么
点语法是方括号语法的特殊形式
属性名是合法标识符的时候才能使用点语法,其他情况可以使用方括号语法
方括号和点语法的区别
方括号语法
对象字面量的增强
调用函数的时候,穿了参数就使用所传的参数,如果没有传参数,就使用默认值
函数参数的默认值什么?
不传参数或者参数为undefined,默认值才会生效
如果默认值是表达式,表达式是惰性求值
默认值是表达式的情况
从函数参数的右边开始设置默认值
小技巧
函数参数默认值的注意事项
当传入很多很多参数的时候,可接收一个对象作为参数
函数参数默认值的应用
函数参数的默认值
对象字面量的增强和函数参数的默认值
当不知道传入多少参数时,使用...加一个参数名老表示剩余参数
剩作为函数参数时,余参数永远是个数组,即使没有值也是个空数组
什么是剩余参数
箭头函数如果只有一个剩余参数,也不能省略圆括号
箭头函数的剩余参数
const add = (...args)=>{}
因为箭头函数中没有arguments
使用剩余参数代替arguments
只能是最后一个参数,后面不能再有参数了,否则会报错
剩余参数的位置
使用剩余参数的注意事项
数组
对象,这里就是剩余元素,是一个对象而不是数组了
应用
剩余参数
...[数组]
将数组形式转化为参数列表形式
认识展开运算符
展开运算符和剩余参数的区分
不适用二维数组?
拷贝数组
div style=\
合并数组
const str = 'hello';const arrrrrrr = [...str];
字符串转化为数组
[...arguments]
[...nodeList]
常见的类数组转化为数组
数组的展开运算符
对象不能直接展开,需要放在{}中展开
把属性罗列出来,放在一对大括号中,构成一个新的对象
展开对象
前后属性名相同的,后面的覆盖前面的,属性名不同的都保留
合并对象
其实没有效果,得到的还是空对象
空对象的展开
数值、undefined、null、布尔等,展开得到的还是空对象
如果展开的不是对象,则会将其先转化为对象再展开
类数组对象
{...'hello'}
字符串的展开
非对象的展开
和在对象中展开一个字符串效果一样
在对象中展开一个数组
不会再对象中再次展开里面的对象
疑问:对象中含有对象复制是否有问题?
复制对象
用户参数和默认参数
实际应用
对象的展开运算符
展开运算符
剩余参数和展开运算符
reduce
和数组有些相似之处
Set是一系列无需的、且没有重复值的数据集合
只能通过new Set() 来创建,不能通过字面量创建
Set没有下标去标识每一个值,所以Set是无序,不能像数组那样通过下标获取到对应的值
Set是什么
添加成员,可以连缀
实例.add();
是否包含某成员
实例.has();
删除某成员,删除不存在的成员也不会报错
实例.delete();
清空
实例.clear();
按照成员添加的顺序遍历的
forEach遍历set
方法
值的个数
实例.size
属性
Set实例的方法和属性
字符串
arguments、NodeList
Set
Set构造函数的参数
Set对重复值的判断基本遵循严格相等===,但对于NaN不一致,Set中NaN等于NaN
判断重复值的方式
数组或字符串去重
不需要通过下标访问,只需要遍历
为了使用Set的方法和属性时
什么时候使用Set
Set的注意事项
Set可以展开
数组去重
字符串去重
单词去重
Set在实际开发中的应用
和对象有相似之处
对象一般用字符串当做键,Map的键没有限定,引用类型也可以当做键
Map和对象的区别
Map是键值对的集合
只能通过new Map(),没有字面量
Map是什么
可以连写,重复的key后面覆盖前面的
.set();
get不存在的键结果是undefined
.get(key)
判断key是否存在
.has(key)
删除一个不存在的key不会报错,返回false
.delete(key)
清空map
.clear()
.forEach
.size;
Map实例的方法和属性
只能传二维数组,并且要体现出键值对
也只能是键值对形式
相当于复制了新的Map但map中值是引用类型的还是原来的引用
Map
Map构造函数的参数
基本遵循严格相等===,NaN例外,Map中NaN和NaN相等
判断键名是否重复的方式
如果只是使用key->value的形式,或者需要字符串以外的值做键,考虑使用Map。只有模拟现实世界的实体时,才用对象
什么时候使用Map
Map的注意事项
见案例
Map实际开发中的应用
Set和Map数据结构
Iterator是遍历器,用来遍历的
Symbol.Iterator(可遍历对象的生成方法)-> it (可遍历对象)->it.next() ->it.next()->……->直到done为false
遍历的过程
数组的iterator对象
这里的it就是可遍历对象
寻找数组的Iterator并使用
Iterator是什么
数组可以使用for循环,forEach等,对象可以用for in。Iterator是一个统一的遍历方式
为什么需要Iterator遍历器?
我们不会直接去使用Iterator,已经有封装好的方便的用法,底层是用了Iterator
如何更方便的使用Iterator?
Iterator解惑
底层是Iterator
只会遍历出done为false时对应的value值
认识for……of……
break终止循环
continue跳出本次循环
与break、continue一起使用
keys()得到的是索引的可遍历对象
也可以使用values() 得到值的可遍历对象
在for……of中如何取到数组的索引
在for of中同时取到值和索引
只要有Symbol.Iterator方法,并且这个方法可以生成可遍历对象,就是可遍历的
只要可遍历,就可以通过fo……of循环来统一遍历
什么是可遍历
原生可遍历
一般的对象
非原生可遍历
原生可遍历和非原生可遍历
for……of……
Symbol 是 ES6 中引入的一种新的基本数据类型,用于表示一个独一无二的值。它是 JavaScript 中的第七种数据类型,与 undefined、null、Number(数值)、String(字符串)、Boolean(布尔值)、Object(对象)并列。
const a = Symbol();console.log(a); //Symbol()console.log(typeof a) // 类型是:Symbol
一、什么是Symbol
let a = Symbol();let b = Symbol();console.log(a); //Symbol()console.log(b); //Symbol()console.log(a === b) // false
可以传入字符串
let a = Symbol(\"symbol1\");let b = Symbol(\"symbol2\");console.log(a); //Symbol(\"symbol1\")console.log(b); //Symbol(\"symbol2\")
1、基本语法
let s1 = Symbol('a');let s2 = Symbol('b');// 由于 s1 和 s2 是一个变量,而不是字符串,因此需要使用中括号括起来(否则它会被当做字符串使用)let a = { name: \"夕山雨\
以 Symbol 类型的变量作为对象属性时,该属性不会出现在 for … in、for … of循环中(后面小节就会讲解for…of循环的)。
2、遍历
let a = Symbol.for('imooc'); //全局注册了以\"imooc\"为描述符的 Symbol//由于描述符\"imooc\"已被注册到全局,因此这里创建的 Symbol 与上面是同一个let b = Symbol.for('imooc'); console.log(a === b) // true
(1)Symbol.for():Symbol 提供的一种可以创建相同 Symbol 的机制,就是使用 Symbol.for()方法进行注册
let a = Symbol.for('imooc');let res = Symbol.keyFor(a)console.log(res) // imooc
(2)Symbol.keyFor():返回一个全局注册的 Symbol 的描述符
3、Symbol.for(),Symbol.keyFor()
二、Symbol语法规范
span style=\
三、symbol-的作用
四、常用内置的-symbol-值:symbol.iterator
【拓展】Symbol详解
只要是可遍历的,都可以按照数组的形式运算展开运算符展开,这就是为什么set、map、字符串、arguments、类数组等可以直接展开
只要是可遍历的,都可以按照数组的形式进行解构赋值,这就是为什么set、map、字符串、arguments、类数组等也可以解构赋值
Set、Map的构造函数
for……of
使用了Iterator的场合
Iterator遍历器和for…of…循环
字符串中是否包含某些字符
第二个参数:开始搜索的位置,不传,默认为0
includes()
原字符串不会被截掉,补全字符串长度(从头部开始补全、从尾部开始补全)
没投传补全的字符串,会用空格补全
padStart()和padEnd()
去除字符串的首尾空格,字符串中间的空格不会去除
trimStart()和trimEnd()
replaceAll()
字符串的新增方法
基本遵循严格相等===,但NaN不同,includes中认为NaN相同
数组中是否含有某个成员
第二个参数时起始搜索位置,不传默认为0
把其他数据转化为数组
字符串、Set、Map、NodeList、arguments等
哪些可以转换为数组
第二个参数:类似于数组的map()方法,对得到的值做一些处理
第三个参数:给第二个函数传入this指向
Array.form()
找到某个值(找到符合的哪一个立即返回值)、找到某个值对应的索引(找到符合的哪一个立即返回其索引)
回调函数的参数:值value、索引index、数组自身
第一个参数是回调函数
同Array.form()的第三个参数,注意箭头函数没有this
第二个参数是this指向
find() 和 findIndex()
数组的新增方法
将属性直接合并到了第一个参数对应的对象中,返回的就是合并后的对象
为了防止第一个参数被修改,一般将一个空对象作为第一个参数
会将基本数据类型转换为对象,再合并。与对象的展开类似
如果基本类型作为源对象时(源是指第2个参数或者第n个参数,第一个参数时目标对象)
后面的会覆盖前面的
同名属性覆盖
合并用户参数和默认参数
Object.assign()
得到对象的键的数组
Object.keys()
得到对象键对应值的数组
Object.values()
得到一个二维数组,二维数组里面的数组,第一个值是键,第二个值是键对应的值
Object.entries()
对象返回的是数组,数组的返回的是可遍历对象Iterator
返回值
数组是实例方法,对象是构造函数方法
调用者
以上3个和数组遍历中的区别
注:不保证顺序
使用for……of遍历对象
获取对象键值等
对象的新增方法
ES6的新增方法
在没学习Promise之前,是用回调函数来处理的,两者也会配合使用
异步操作的一种解决方案
什么是Promise?
用来解决层层嵌套的回调函数(回调地狱 callback hell)的问题
什么时候使用Promise?
入参是一个回调函数
实例化构造函数生成实例对象
一开始是pendding(未完成),执行resolve,变成fulfilled(resolved),已成功
一开始是pendding(未完成),执行reject,变成rejected,已失败
有3种状态
Promise的状态一旦变化,就不会再改变了
Promise的状态
入参是两个回调函数,第一个是fulfilled的时候调用的,第二个是rejected时候调用de
then()方法
resolve的参数,就是then第一个回调函数里可以接受的参数,比如reject参数可以是new的一个Error对象
resolve()、reject()函数的参数
Promise的基本使用
初识Promise
当pendding->fulfilled,执行then的第1个回调函数
当pendding->rejected,执行then的第2个回调函数
什么时候执行?
then方法执行之后返回一个新的Promise对象,和原来的Promise对象没有关系
then一般会连写
执行后返回值是什么?
then默认返回的是成功状态的Promise对象
在then回调函数体中,return后面的东西会使用Promise包装一下
返回的Promise对象的状态如何改变?
向后传值
使用Promise解决回调地狱问题
then()
一般用then()只处理成功的状态,使用catch()方法可以专门用来处理rejected状态,本质上是then的特例
catch可以捕获前面的错误,一般总是建议,Promise对象后面要跟catch,这样可以处理Promise内部发生的错误
catch()
也是then的特例
当Promise的状态发生变化的时候,不论如何变化都会执行,不变化不执行
什么时候会执行?
finally()
Promise的实例方法
简写:省略大括号
成功状态的一种简写形式
本质
一般参数
以下两种写法是等价的
当Promise.resolve接收的参数是Promise对象时,什么都不做,直接返回这个对象
Promise实例的resolve()方法,如果是结构的Promise对象,也是根据传入的Promise对象的状态变化来决定then执行哪一个回调
Promise对象作为参数
具有then方法的对象(用的不多)
参数
在then方法中的应用
Promise.resolve()
失败状态的一种简写形式
不管什么参数,都会原封不动的向后传送,作为后续方法的参数
Promise.reject()
用来关注多个Promise对象的状态的变化
传入多个Promise实例,包装成一个新的Promise实例返回
作用
子主题
Promise.all()的状态与传入的Promise实例对象状态有关。所有的状态都变成resolved,最终才是resolved;只要有一个是rejected,最终状态就是rejected
基本用法
Promise.all()
race就是竞赛的意思
Promise.race()的状态取决于第一个完成的Promise对象,第一个完成的成功了,那最终状态就是成功;第一个失败了,那最终状态就是失败
Promise.race()
Promise.allSettled()与传入的Promise对象的状态无关,永远都是成功的。它只会忠实的记录下每个Promise的表现
Promise.allSettled()
传入的参数是一组Promise实例,那么所有Promise实例都变成rejected状态,返回的Promise才会变成rejected状态参数中只要有一个Promise改变为成功状态,则返回的Promise状态就是成功的状态。只要有一个成功就会终止
实际开发中,可能会有这样的需求:一次性加载多张图片,哪一张先加载出来就显示哪一张。那么此时就可以使用Promise.any()方法实现效果。
使用场景
Promise.any()
Promise的几个构造方法
如果调用了resolve()或者reject()之后,如果后面还有代码,在return之前的代码是会执行的
建议在resolve()或者reject()前加上return,不再执行后面的代码,后面的代码放在后续的then里执行
resolve和reject执行后的代码
参数如果不是Promise对象数组,会将不是Promise对象的数组元素转化为Promise对象
不只是数组,任何可遍历的对象都可以传入
Promise.all()、Promise.race()、Promise.allSettled()等参数的问题
错误既可以单独处理,也可以统一处理,错误一旦被处理,就不会在其他地方再处理一遍
Promise.all()、Promise.race()、Promise.allSettled()等的错误处理
Promise的注意事项和应用
async/await是基于Promise实现的。
async/await使得异步代码看起来像同步代码。
什么是async/await
async 函数返回一个 Promise 对象,可以使用 then 方法添加回调函数。 当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再接着执行函数体内后面的语句。
async/await语法规范
2、await 后面跟着是一个Promise对象, 会等待Promise返回结果了,再继续执行后面的代码。
3、await 后面跟着的是一个数值或者字符串等数据类型的值,则直接返回该值
可以直接用标准的try catch语法捕捉错误
错误捕获
【扩展】async/await
ES6之Promise
人类:类具体的人:实例/对象
类可以看做事对象的模板,用一个类可以创建出多个不同的对象
JS中的类建立在原型上
什么是class
实例化时会执行构造方法,所以必须有构造方法但可以不写出来,不写就用默认的构造方法
一般在构造方法中定义属性,不再构造方法中定义方法(因为每次创建一个对象就会创建一个方法,创建出来的方法并不是同一个引用,会浪费大量内存)
class基本用法
class Person { constructor(span style=\"color: #001080;\
声明形式
将一个匿名的类赋值给一个常量
立即执行的class
表达式形式
class两种定义形式
class的typeof是function
class底层是由构造函数实现的
class中添加的方法(不是在构造方法中添加的)就是在原型上的方法
class与构造函数区别
初识class
实例属性
class Person{ static say(){ }}
但不是很推荐这种写法
Person.say=function (){}
在class中使用static关键字修饰,可以和实例方法同名不会冲突,直接用类打点调用,不需要实例化
静态方法中的this指向的是类本身,而不是实例化出来的对象
静态方法就是类的方法
静态方法通常用于为一个应用程序创建工具函数。
静态方法
静态属性就是类的属性,要和实例属性区分开
静态属性
声明的类的属性和方法只能在类内部使用的,称之为私有
一般情况下,类的属性和方法都是公开的
目前没有支持的只能在类内部使用的属性和方法,需要模拟
为什么需要私有属性和方法
并不能强制不能再类外访问,还是可以访问的,只是约定俗成的不去访问
下划线开头表示私有,一种约定。在定义一个方法返回这个属性,类外部通过调用这个方法获取
将类的声明写在一个IIFE中,私有属性或方法定义在类外,将类赋值给window;在另一个IIEF中实例化类。
江苏有属性和方法移出类
模拟私有属性和方法
私有属性和方法
Class的属性和方法
使用extends会继承父类的:属性、实例方法、静态方法、静态属性等。
子类继承父类
子类中写了和父类同名的方法,会同名覆盖。子类中新增的,只有子类有。
子类改写继承的属性或方法
extends
代表父类的构造方法,只能用在子类的构造方法中,在其他地方使用会报错。这种情况,在子类中调用super相当调用父类的构造方法
super在子类中,this指向的是子类的实例,而不是父类
作为函数调用
可以在子类中调用父类的方法
通过super调用父类的非静态方法时,方法内部的this指向的是当前子类的实例
定义在父类实例上的方法和属性,使用super在子类中不能访问到
在构造方法中或非静态方法中使用此时super代表父类的原型对象,Parent.prototype
可以使用子类调用父类的静态方法
通过super调用父类的静态方法时,方法内部的this指向的是当前子类本身而不是子类实例
在静态方法中使用此时super代表父类本身而不是原型对象也不是实例
作为对象使用
使用super时,需要显性的指出是作为函数还是作为对象使用,否则会报错
当子类继承父类时,如果不需要通过constructor设置属性和继承父类constructor中的属性,那么就可以不写constructor和super,否则,就必须写上constructor和super。
super
Class的继承
幻灯片
Class实际开发中的应用
ES6之Class类
一个一个的局部作用域的代码块
什么是模块
解决模块化的问题
消除全局变量
管理加载顺序
模块系统解决的问题
什么是模块系统
Module是什么
使用Module模块化之前的例子
一个文件就是一个模块了
<script src=\"./js/index.js\" type='module'></script>
<script type='module'> import './module-0.js';</script>
只要你会用到import或export,在script标签加载时候,就要加上type=\"module\"
使用script标签加载标签
Module如何解决模块化的问题的
Module的基本用法
初识Module
导出的东西可以被导入(import),并访问到
import './js/base.js';
一个模块没有导出,也可以被导入,被导入的代码都会被执行一遍,多次导入,也仅执行一遍
认识导出和导入
一个模块只能有一个export default
import和export default对应使用的时候,import可以随便取别名,不一定和export default后的一样
export default XXXX;import xxxx from './js/xxxxxxx.js';
export default导出一个默认值
export default 和对应的import
export const name = 'zhangsan';
const name='zhangsan';export {name};
export的两种写法
这里的name必须和上面的export后的名字一样,不能随意取名
import {name} from './js/xxxxxx.js';
import的写法
export后面跟声明或语句
const name = 'zhangsan';const fun = function (){};class Person{}const p = { d: \"ddd\
可以不按照导出的顺序,只要名字对应上即可
多个导出多个导入
import { func as span style=\"color: #001080;\
export { name as span style=\"color: #0070c1;\
使用as取别名
导入导出时起别名
使用*号导入整体,使用as取个别名,这种写法也会导入xeport default导出的内容
import * as obj from './module-0.js';div style=\
整体导入
span style=\"color: #af00db;\
前面的age是export defaul所导出的,一定要将这个放在前面,否则报错
同时导入export以及export default所导出的内容
同时导入
export和对应的import
Module的导入和导出
可以利用这个特性,如果script标签没有使用type='module'那就会按照普通模式加载而不是模块化了,可以在js模块中判断,顶层this是否是undefined,如果不是,就要给出提示,按照模块化加载js
在模块中,顶层的this指向undefined
模块顶层的this指向
比如不能放在if判断中
import命令具有提升效果,会提升到整个模块的头部,率先执行import执行的时候,代码还没有执行。import和export命令,只能用在模块的顶层,不能在代码块中执行
目前import()只是一个提案,可能存在兼容性问题,后续可以结合webpack使用
const PC = true;const Mobile = false;if (PC) { import('./module.js').then( () => { console.log(span style=\"color: #a31515;\
import()返回的是一个Promise对象,后面可以跟then() catch()等
import()函数可以实现按条件导入
import关键字和import() 函数
可以从一个模块导入然后再导出给其他模块使用,相当于一个中转站
但复合写法导出的无法在当前模块使用
import {version} from './base.js';export {version};
相当于
export { version } from \"./base.js\";
导入导出的复合写法
Module的注意事项
将默认值等单独拆出一个模块文件,然后将自己导出给其他模块用
将所有常量可以单独拆出一个模块文件,然后将自己导出给其他模块用
相对独立的功能都可以拆出来,注意this
如何更合适的拆分,需要多练多用
Module在实际开发中的应用
ES6之Module(模块)
Babel是Javascript的编译器,用来将ES6的代码转换为ES6之前版本的代码(ES3、ES5等)
官网:https://babeljs.io/
在线编译:https://babeljs.io/repl
认识Babel
Babel本身可以编译ES6的大部分代码,比如let、const、箭头函数、类等。但是对于ES6新增的API,如Set、Map、Promise等全局对象,以及定义在全局对向上的方法(如Object.assign\\Array.fromd等),都不能直接编译,需要借助其他模块
Babel一般要配合Webapck来编译模块(Module)语法
使用Babel
解释编译结果
Bable是什么
推荐CLI和Webpack结合
在命令行工具中使用Babel
Babel的使用方式
Node.js是一个平台或者工具,对应浏览器。在这个平台上使用的语言是Node.js,一种后端的Javascript
后端的Javascript=ECMAScript+IO+FIle+……+等服务端的操作
通俗的,一般将后端的Javascript成为Node.js
Node.js
node包管理工具
npm
什么是Node.js和npm
node -v
npm -v
下载包并安装会同时安装好Node 以及npm
官网:https://nodejs.org/en/
安装Node.js
初始化项目
1、npm init
使用npm安装包的时候会将安装的情况记录在这个文件中。比如更换开发环境、更换电脑,不需要将下载的包复制一份,只需要有这个文件就可以了可以再使用一些命令,将安装过的包全部再安装一遍就好了
2、初始化之后,会在项目目录下生成一个package.json
在项目目录中
只执行一遍,切换安装源,从国外切换到国内
测试:npm config get registry
npm config set registry https://registry.npm.taobao.org
--save-dev是指开发依赖
\"devDependencies\": { \"@babel/cli\": \"^7.15.4\
执行完之后会在刚刚的package.json中增加以下内容
指向完成后会在当前项目目录下生成安装包的目录node_modules如果这个包丢失,但package.json文件保留,可以在当前项目目录下执行npm install 可以下载package.json中指定的所有包
根据官网的提示执行:npm install --save-dev @babel/core @babel/cli
可以使用@安装指定版本npm install --save-dev @babel/core@7.11.0 @babel/cli@7.10.5
安装Babel需要的包
Babel使用前的准备工作https://babeljs.io/setup#installation
这里的build就是后面一行命令的一个简写,取名字
src指ES6的代码目录
输出到dist目录
-d dist => -out-dir dist
\"scripts\": { \"build\": \"babel src -d dist\
根据官网提示添加
编译的命令
npm install @babel/preset-env --save-dev
安装Babel的包
为了启用预设,您必须在babel.config.json文件中定义它,如下所示:{ \"presets\": [\"@babel/preset-env\"]}
创建Babel配置文件
Babel配置文件
使用Babel编译ES6代码
Babel
Webpack是静态模块打包器,当Webpack处理应用程序时,会将所有这些模块打包成一个或多个文件
ES6中的Module语法,就是用webpack来处理
可以理解为:Webpack可以处理的最小单位
ES6中的Module模块,属于Webpack模块。Webpack还可以处理css/js/图片、图标字体等单位。----都可以称之为Webpack模块
Webpack中的模块是什么?
开发过程中存在于本地的css/js/图片、图标字体等文件,就是静态的
动态的内容(比如图片再服务器端存放),Webpack没法处理,只能处理静态的
Webpack中静态是指什么?
认识Webpack
Webpack是什么
npm init
npm install --save-dev webpack-cli@3.3.12 webpack@4.44.1
安装Webpack需要的包
webpack.config.js
配置文件
\"webpack\": \"webpack --config webpack.config.js\"
配置文件内容
配置Webpack
打包并测试
Webpack初体验
Webpack入门
entry: \"./src/index.js\
单个入口文件
多个入口文件
指定入口文件
entry
__diename只当前项目目录,绝对路径
resolve是拼接自己的两个参数
filename,指定输出文件名字
const path = require(\"path\
单入口文件对应的输出
中括号[name]就是entry多个入口文件对应的最前面的名字
多入口对应的输出
指定出口
output
entry和output
loader就是让Webpack能够去处理非JS模块。loader被用于转换某些类型的模块
学会从官网查找更多的loader使用配置。官网地址:https://www.webpackjs.com/loaders/
什么是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-loader
创建babel配置文件
官网地址:https://babeljs.io/docs/en/babel-polyfill
npm install --save-dev core-js@3.6.5
在我们的源码入口js文件头部增加:import \"core-js/stable\";
npm run ……
打包测试
引入core-js模块,用来编译ES6新增的PAI,比如Promise等这样引入编译后的js文件在IE浏览器中测试时能通过的
babel-loader
loader
官网地址:https://www.webpackjs.com/plugins/
loader被用于转换某些类型的模块,而插件可以用于执行范围更广的任务。
插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量
什么是plugins
npm install --save-dev html-webpack-plugin@4.3.0
安装html-webpack-plugin插件
// 导入html-webpack-plugin插件const HtmlWebpackPlugin = require(\"html-webpack-plugin\");
plugins: [ // 如何使用插件,这里实例化一下上面定义的 new HtmlWebpackPlugin({ template: \"3.html\
单页面-配置html-webpack-plugin插件(webpack配置文件)
entry: { main: \"./src/index.js\
plugins: [ // 多入口文件--实例化多次 new HtmlWebpackPlugin({ template: \"index.html\
多入口页面-配置html-webpack-plugin插件(webpack配置文件)
以html-webpack-plugin为例学习
plugins
Webpack核心概念
npm install --save-dev css-loader@4.1.1
webpack只会处理js文件,js以外的文件借助loader处理
需要安装css-loader并配置
npm install --save-dev style-loader@1.2.1
需要安装style-loader并配置
1、以style标签形式嵌入html页面
也需要安装css-loader并配置
npm install --save-dev mini-css-extract-plugin@0.9.0
new MiniCssExtractPlugin({ // [name] 表示取entry中的名字,没有默认为main filename: \"css/[name].css\
需要使用插件mini-css-extract-plugin并配置
处理css文件
如果图片是服务器的图片,不需要webpack处理。正常就可以执行
npm install --save-dev file-loader@6.0.0
file-loader将图片从源码复制了一份到输出目录,并重新取了名字并修改了css引入图片的路径
需要安装file-loader并配置
使用file-loader处理css中的图片
npm install --save-dev html-withimg-loader@0.1.16
需要安装html-withimg-loader并配置
使用html-withimg-loader处理html中的图片
import imgUrl from \"./images/1.jpg\";
使用file-loader处理js中的图片
npm install --save-dev url-loader@4.1.0
处理一些base64的图片,功能包含file-loader,后续可以统一使用url-loader
url-loader是以file-loader为基础的,所以file-loader包也需要下载
//url-loader配置,小于10K的图片都会转成base64的格式limit:10000
配置和file-loader相同,功能相似,可以处理css、js图片,但不能处理html引入的图片。多了一个可以base64编码的功能
使用url-loader处理图片
npm install --save-dev webpack-dev-server@3.11.0
安装webpack-dev-server
使用Webpack-dev-server搭建开发环境
Webpack的应用
Webpackhttps://www.webpackjs.com/
ES6之Babel与Webpack
ES6基础
ES6
收藏
0 条评论
回复 删除
下一页