变量常量
1.let,var和const的用法
var usename ='Alex'
let age = 18
const sex = 'nale'
console.log(usename,age,sex)
2.什么是变量,什么是常量
var usename = 'alex'
usename ='ZS' //var/let 变量,初始化之后还可以重新赋值
const age = 18
age = 19 //const 常量,一旦初始化,就不能重新赋值,否则报错
3. 重复声明
var i = 10
var i = 20 //var允许重复声明
let i = 10 //报错,let与const不允许重复声明
4.变量提升
consle.log(a) //undefined var会提升变量声明到当前作用域的顶部
var a = 10
只要作用域内存在let,const,他们所声明的变量过常量就自动"绑定"这个区域,不再受到外部作用的影响,let const存在暂时性死区
fuction fun(){
console.log(a)
let a = 1
}
5.全局/局部作用域
var没有块级作用域
for(var i = 0 ; i < 3 , i ++){
console.log(i) //0 1 2
}
consle.log(i) //3
let/const 有块级作用域
for(let i = 0 ; i < 3 ; i++){
consle.log(i) // 0 1 2
}
console.log(i) //报错
模板字符串
1.模板字符串与一般字符串的区别
const prenson = {
name:"王浩然",
age: 17,
}
const info ="我的名字是:"+prenson.name+",我的年龄是"+prenson.age;//一般字符串
console.log(info) //我的名字是王浩然,我的年龄是17
const infos =`我的名字是${prenson.name},我的年龄是${prenson.age}`//模板字符串我的名字是王浩然,我的年龄是17
console.log(infos) //我的名字是王浩然,我的年龄是17
//使用模板字符串方便注入
2.输出`和\等特殊字符
const info = `\` \\`
console.log(info) // `\
箭头函数
1.箭头函数结构
const/let 函数名 = 参数 =>函数体
const add = () =>{}
2.单个参数可以省略圆括号
const add = x =>{
return x+1
}
3.不适合箭头函数的场景
// 1.作为构造函数 箭头函数没有this
const Person = () =>{}
new Person()
// 2.需要this指向调用对象的时候
document.onclick = function(){
console.log(this)
}
document.addEventLIstener(
'click'
() =>{
console.log(this) //window
),
false
}
// 3.需要使用argunments的时候
function(add){
console.log(argunments)
}
add(1,2,3,4,5)
const add = () => conslole.log(argunments)
this指向
1.全局作用域的this指向
console.log(this) //window
2.普通函数指向
function fn(){
consloe.log(this) //window
}
3.箭头函数指向
const calc = {
add: function () {
const adder = () => {
console.log(this);
}
adder()
}
}
calc.add() //calc
解构赋值
1.认识结构赋值
const arr =[1,2,3,4,5]
const a = arr[0]
const b = arr[1]
const c = arr[2]
constle.log(a,b,c) // 123
const [a,b,c] = [1,2,3]
console.log(a,b,c) //123
// 解析某一数据的结构,将我们想要的东西提取出来.赋值变量或常量
2.索引值相同的完成赋值
const [a,[,,b],c] = [1,[2,4[5],3]
console.log(a,b,c) //123
// 不取值的,可以用逗号跳过
3.默认值的基本用法
const [a,b] = []
const [a,b] = [undefined,undefined]
const [a=1, b=2] = []
console.log(a,b)
4.默认值的生效条件
// 只有当一个数组成员严格模式等于(===)undefined时.对应的默认值才会生效
const [a=1,b=2] = [3,0]
const [a=1,b=2] = [3,null]
const [a=1,b=2] = [3]
console.log(a,b)
5.默认值表达式
//如果默认值是表达式,默认值表达式是惰性求值的
const func = () => {
console.log("我被执行力")
}
const [x=func()]=[]
cconsole.log(x)
6.undefined和unll的解构赋值
//🦑undefin和null无法转为对象,所以对它们进行解构赋值.会报错
const [toString] = undefined // 报错
const [toString] = null // 报错
函数参数默认值
1.函数参数默认值的基本用法
cibst num = (x,y=999) => x * y
console.log(num(2)) //1998
// 不传参数.或者明确的传递undefined作为参数,只有这两种情况下,默认值才会生效
// 如果默认值是表达式,默认值表达式是惰性求值的
剩余参数
1.剩余参数的本质
const add =(x,y,z,...args) => {
console.log(x,y,z,args) // 1 2 3 [4,5]
}
add(1,2,3,4,5)
// 剩余参数永远是个数组,即便没有值也是空数组
2.剩余参数的位置
//剩余参数只能是最后一个参数,否则报错
const add = (x,...args,i) => {} // 报错
3.与解构赋值结合使用
// 剩余参数不一定要作为函数使用
const [num,...ags] = [1,2,3,4]
const func = (num,...argg) => {}
func(1,2,3)
const {x,y,...z} = {a:3,x:1,y:2,b:2}
console.log(x,y,z) //1 2 {a:3,b:2}
展开运算符
1.数组展开运算符的基本用法
cosole.log(Math.min(...[3,2,1])) //1
2.合并数组
const a = [1,2]
const b = [2,3]
const c = [3,4]
console.log([...a,...b,...c) //[1,2,2,3,3,4]
对象的展开运算符
1.展开对象
//对象不能直接展开,必须在{}中展开
const apple = {
color :"蓝色",
shape :"方形",
taste :"苦",
}
console.log({...apple}}
2.合并对象
//相同属性后者覆盖前者
const pen = {
color :"五颜六色",
shape :"长方体",
taste :"甜",
}
console.log({...apple,...pen})
set
1.方法
// add
const s = new Set()
s.add(1),add(2)
console.log(s) // set(2) {1,2}
//删除成员
s.delete(1)
//全删
s.clear()
2.判断重复
const s = new Set([1,2,1])
console.log(1 === 1) //true
// Set对重复值的判断基本遵循严格先等(===)
// 但是对于NaN的判断与===不同,Set中的NaN等于NaN
3.什么时候用set
//数组去重的时候
//不需要通过下标访问,只需要遍历时
//为了使用set提供的方法和属性时(add delete clear has forEach size 等)
4. 去重
console.log([...new Set([1,2,3,1])])
//字符串
console.log([...new Set('abbbbwds')].join(''))
5.更改dom元素
const = new Set(document.querySelectorAll('p')
s.forEach(function(elem){
elem.style.color = 'red'
}
Map
1.认识Map
// 键 -> 值 , key -> value
const person = {
name:'alex',
age:18
}
const m = new Map()
m.set('name','alex')
m.set('age'.18
2.map和对象的区别
//对象一般用字符串当键
const boj = {
name:'alex',
true:'true',
[{}]:'object'
}
console.log(obj)
//引用和基本数据类型都可以作为map的键
3.方法
const m = new Map()
//使用set添加的新成员,键如果已经存在,厚添加的键值对覆盖已有的
m.set('age',18).set(true,'true').set('age',20)
4.数组
new Map([
['name','alex'],
['age',18]
])
sonst s = new Set([
['name','alex'},
['age',18]
])
5.更改dom元素
const m = new Map([
[p1,'red'],
[p2,'green'],
[p3,'blue']
])
m.forEach((color,elem) => {
elem.style.color = color
}
遍历
1.iterator
// iterator:遍历器(迭代器)
//寻找iterator
console.log([1,2][Symbol.iterator]())
//使用iterator
const it = [1,2][Symbol.iterator]()
console.log(it.next())
console.log(it.next())
console.log(it.next())
//Symbole.iterator(可遍历对象的生成方法) -> it(可便利对象) -> it.next() -> it.next()...直到done为true
//一般不会直接使用iterator去遍历 用for..of
for of
const arr = [1,2,3]
for(const item of arr){
console.log(item)
}
// for..of循环只会遍历那些done为false时对应的value值
//与break和continue一起使用
const arr = [1,2,3,4]
for (const item of arr){
if(item ===2){
// break
continue
}
console.log(item);
}
//在for of中取得数组的索引
const arr = [1,2,3]
console.log(arr.keys());
for(const key of arr.keys()){
console.log(key);
}
//entries()得到的是索引+值组成的数组的可遍历对象
for (const entiries of entiries){
console.log(entiries);
}
原生,非原生可遍历
//只要有symbol.iterator方法,并且这个方法可以生成可遍历对象,就是可遍历
//原生可遍历 数组,字符串,set,map,arguments,nodelist
for(const item of[1,2,3]){
console.log(item);
}
for(const item of 'hi'){
console.log(item);
}
for(const item of new Set([1,2])){
console.log(item);
}
for(const elem of Document.querySelectorAll('p')){
elem.style.color = "red"
}
//非原生可遍历的有哪些]
const person = {sex:'male',age:18}
person[Symbol.iterator] =() =>{
let index = 0
return{
next(){
index++
if(index == 1){
return{
value:person.age,
done:false
}
}
else if(index == 2){
return{
value:person.sex,
done:false
}
}
else{
return{
done:true
}
}
}
}
}
for(const item of person){
console.log(item);
}
//有length和索引属性的对象
const obj = {
0:'alex',
1:'male',
length:2
}
obj[Symbol.iterator] =()=>{
let index = 0
return{
next(){
let valeu,done;
if(index <obj.length){
value = obj[index]
done= false
}else{
value = undefined
done = true
}
index++
return{
value,
done
}
}
}
}
for (const item of obj){
console.log(item);
}
字符串的新增方法
1.includes()
//基本用法
console.log('abc'.includes('a'));//true
console.log('abc'.includes('ab'));//true
console.log('abc'.includes('bc'));//true
console.log('abc'.includes('ac'));//false
//第二个参数
//表示开始位置,默认是0
console.log('abc'.includes('a'));
console.log('abc'.includes('a',0));
console.log('abc'.includes('a',1));//false
//应用
let url =''
const addURLParam = (url,name,value) =>{
url += url.includes('?')? "&":"?"
url += `${name}=${value}`
return url
}
url = addURLParam(url,'c','fe')
console.log(url);
url = addURLParam(url,'sort','pop')
console.log(url);
//判断数组是否含有某个成员
console.log([1, 2, 3].includes('2'))//false
console.log([1, 2, 3].includes(2))//true
//基本遵循严格相等,但是对于nan的判断与===不同,认为nan===nan
console.log([1, 2, NaN].includes(NaN))//true
//去重
const arr = []
for (const item of [1, 2, 3]) {
if (!arr.includes(item)) {
arr.push(item)
}
}
console.log(arr);
2.padStart()和padEnd()
//基本用法
console.log('x'.padStart(5,'ab'));//ababx
console.log('x'.padEnd(5,'ab'));//xabab
console.log('x'.padEnd(4,'ab'));//xaba
//原字符串长度,等于或大于长度,不会消减原字符串,字符串补全不生效
console.log('abc'.padEnd(10,'123456789'));
console.log('x'.padStart(4));//填充空格
//应用 显示日期格式
console.log('10'.padStart(2,0));//10
console.log('1'.padStart(2,0));//01
3.trimStart()和trimeEnd()
//清除字符串首尾空格,中间的空格不会清楚
const s = ' a b c '
console.log(s.trimStart()); //a b c
console.log(s.trimEnd()); // a b c
console.log(s.trim()); // 两头全去
//应用
const usernameinput = document.getElementById('username')
const btn = document.getElementById('btn')
btn.addEventListener('click',
() =>{
console.log(usernameinput.value);
if(usernameinput.value.trim() !==''){
console.log('可以');
}else{
console.log('不能');
}
},false
)
数组新增方法
Array.form()
console.log(Array.form('str'));
//Array.form可转化的,数字,字符串,set,map,nodelist,aerguments
console.log(Array.form(new Set([1,2,1])));
console.log([...new Set([1,2,1])]);
//拥有length属性的任意对象
const obj = {
'0':"a",
"1":'b',
name:'alex',
length:3
}
console.log(Array.form(obj));
// 作用类似于数组的map方法,用来对每个元素进行处理.将处理后的值放入返回的数组
[1,2].map((value)=>{
return value * 2
})
console.log(Array.form('12',value=>value*2));
//修改this指向
Array.form('12',value=>{
'12',
function() {
console.log(this);
}
})
find()和findindex
[1,2,5,10,15].find((value,index,arr)=>{
// console.log(value.index,arr);
console.log(this);
return value>9
},document)
[1,2,5,10,15].findindex((value,index,arr)=>{
// console.log(value.index,arr);
return value>9
})
//应用
students.find(value=>value.sex ==='女')
students.findindex(value=>value.sex ==='女')
对象的新增方法
Object.assign()
//Object.assign 直接合并道第一个参数中,返回的就是合并后的对象
const apple ={
color:'red'
}
const pen ={
color:'bule'
}
console.log(Object.assign({},apple,pen));
//基本数据类型作为源对象
// Object.assign(目标对象,源对象1,2,3,4)
console.log(Object.assign({},undefined));// {}
console.log(Object.assign({},"str"));// {0:'s',1:"t",2:'r'}
//同名属性的替换 后面的直接覆盖前面的
//合并默认参数和用户参数
const logUser = userOpitions =>{
const DEFAULTS = {
username:'zhangsan',
age:0,
sex:'male'
}
const options=Object.assign({},DEFAULTS,userOpitions)
console.log(options);
}
logUser()
Object.keys()、Object.values()、Object.entries()
const pen ={
color:'bule'
}
//获取键
console.log(Object.keys(pen));
//获取值
console.log(Object.values(pen));
//都获取
console.log(Object.entries(pen));
//使用for of 遍历对象
for(const[key,value] of Object.entries(pen)){
console.log(key,value);
}
//并不能保证顺序,一直点和forin是一样的
Promise
基本用法
//Promise是异步操作的一种解决方案 一般用来解决层层嵌套的回调函数
document.addEventListener(
'click',
()=>{
console.log("这里是异步");
},
flase
)
console.log('这里是同步的');
//Promise 解决的不是回调函数,而是回调地狱
// const p = new Promise(()=>{})
//Promise的状态
const p = new Promise((resolve,reject)=>{
//promise 有三种状态,一开始是pending(未完成),执行resolve,变成fulfilled(resolved),已成功
//执行reject,变成rejected,已失效
// primise的状态一旦变化,就不会在改变了
//pending -> fulfillef
resolve()
//pending -> rejected
reject()
})
//then方法
p.this(
()=>{
console.log('success');
},
()=>{
console.log('reeor');
}
)
then
/ pending -> fulfillef时,执行then的第一个回调函数
// pending -> rejected时,执行then的第二个回调函数
// then方法执行后返回一个新的promise对象
const p = new Promise((resolve,reject)=>{
resolve()
// reject()
})
p.then(
data =>{
console.log('su');
},
err =>{
console.log('err');
//在then的回调中,return后面的东西会用promise包装一下
return new Promise((resolve,reject)=>{
resolve()
})
}
).then(
data =>{
console.log("su2");
},
err =>{
console.log('err2');
}
).then(
data =>{
console.log("succ3",data);
},
err =>{
console.log("err3" ,err);
}
)
promise解决回调地狱
const move = (el,point)=>{
return new Promise((resolve)=>{
move(el,point,()=>{
resolve()
})
})
}
document.addEventListener('click',()=>{
move(boxEl,{x:150}).then(()=>{
return move(boxEl,{x:150,y:150})
}).then(()=>{
return move(boxEl,{y:150})
}).then(()=>{
return move(boxEl,{x:0,y:0})
})
},false)
catch()
new Promise((resolve,reject)=>{
// resolve(123)
reject('reason')
}).then(
data =>{
console.log(data);
}).catch(
err=>{
console.log(err);
throw new Error('reason')
}).then(
data=>{
console.log(data);
}).catch(err=>{
console.log(err);
})
//catch()可以捕获它签前面的错误一般总是建议.promise对象跟catch方法, 这样可以处理promise内部发生的错误
finally()
//当promise状态发生时,不论如何都会执行.不变化不执行
new Promise((resoleve,reject)=>{
// resolve(123)
reject('reason')
}).finally(data =>{
console.log(data);
})
.catch(err=>{
})
//finally()本质上是then()的特例等同于
new Promise((resolve,reject)=>{
reject('reason')
})
.then(
result =>{
return result
},
err =>{
return new Promise((resolve,reject)=>{
reject(err)
})
}
)
.then(data=>{
console.log(data);
}).cath(err=>{
console.log(err);
})
构造函数方法
Promise.resolve()和Promise.reject()
//promise resolve()是成功状态promise的一种简写
new Promise(resolve =>resolve('foo'))
//简写
Promise.resolve('foo')
//一般参数
Promise.resolve('foo').then(data=>{
console.log(data);
})
//特殊参数promise
const p1 = new Promise(resolve =>{
setTimeout(resolve,1000,"我执行了")
})
Promise.resolve(p1).then(data=>{
console.log(data);
})
//当resolve函数接受的rromise对象的时候,后面的then会根据传递的promise对象的状态变化决定执行哪一个回调
new Promise(resolve => resolve(p1)).then(data=>{
console.log(data);//我执行了
})
//具有then方法的对象
const thenable ={
then(resolve,reject){
console.log('then');
// return 123
resolve('data')
// reject('reason')
}
}
Promise.resolve(thenable).then(
data=>console.log(data),
err =>console.log(err)
)
console.log(Promise.resolve(thenable));
//promise.reject()失败状态promise的一种简写形式
new Promise((resolve,reject)=>{
reject('reason')
})
//等于
Promise.reject('reason')
//不管什么参数,都会原封不动的向后传递,作为后续方法的参数
const p2 = new Promise(resolve =>{
setTimeout(resolve,1000,"我执行了")
})
Promise.reject(p2).catch(err=>console.log(err))
new Promise((resolve,reject)=>{
resolve(123)
}).then(data=>{
return Promise.reject('reason')
}).then(data=>{
console.log(data);
}).cath(err=>{
console.log(err);
})
Promise.all()
//promise.all()关注多个promise对象的状态变化
//传入多个promise实例,包装成一个新的promise实例返回
const delay = ms =>{
return new Promise(resolve =>{
setTimeout(resolve,ms)
})
}
const p1 =delay(1000).then(()=>{
console.log('p1完成了');
return 'p1'
})
const p2 =delay(2000).then(()=>{
console.log('p2完成了');
return 'p2'
})
//Promise.all()的状态变化与所有传入的promise实例对象状态有关
//所有状态都变成resolved,最终的状态才会变成resolved
//只要有一个变成rejected,罪状的状态就会变成rejected
const p = Promise.all([p1,p2])
p.then(data=>{
console.log(data);
}),err=>{
console.log(err);
}
Promise.race()和Promise.allSettled()
// promise.race()的状态取决于第一个完成的promise实例对象如果第一个成功了,最终成功的就成功.如果第一个失败了,最终的就失败
const delay = ms =>{
return new Promise(resolve =>{
setTimeout(resolve,ms)
})
}
const p1 =delay(1000).then(()=>{
console.log('p1完成了');
return 'p1'
})
const p2 =delay(2000).then(()=>{
console.log('p2完成了');
return 'p2'
})
const reacePRomise = Promise.race([p1,p2])
reacePRomise.then(data =>{
console.log(data);
}),err=>{
console.log(err);
}
// Promise.allSettled状态与闯入的promise状态无关永远都是成功的它只会忠实的记录下各个的promise的表现
const rSettledPRomise = Promise.allSettled([p1,p2])
SettledPRomise.then(data =>{
console.log(data);
})
Promise的应用
//异步加载图片
const loadingimg = url =>{
return new Promise((resolve,reject)=>{
const img = new image()
img.onload = ()=>{
resolve(img)
}
img.onerror =()=>{
reject(new Error(`Colud not load image at ${url}`))
}
img.src =url
})
}
const imgDOM = document.querySelector('img')
loadingimg('https://img').then(img=>{
console.log(img.src);
setTimeout(()=>{
imgDOM=img.src
},1000)
}).catch(err=>{
console.log(err);
})
Class
class与构造函数
//class基本用法 一般首字母大写
class Person{
//实例化时执行构造方法,所以必须有构造方法,但可以不写出来
constructor(name,age){
console.log('实例化时执行构造方法');
this.name=name
this.age=age
}
//各个实例共享方法
speak(){
}
}
// function Person(name,age){
// //实例化时执行构造方法,所以必须有构造方法,但可以不写出来
// console.log('实例化时执行构造方法');
// this.name=name
// this.age=age
// }
// person.prototype.speak= function(){}
</script>
Class的两种定义形式
//声明形式
class Person{
constructor(){
}
speak(){}
}
//表达式形式
// const Person = function(){}
const Person = class{
constructor(){
console.log('1');
}
speak(){}
}
(function(){
console.log('func');
})()
//立即执行类
(new class{
constructor(){
console.log('con');
}
})()
属性方法
实例属性、静态方法和静态属性
//实例属性
//方法就是值为函数的特殊属性
class Person{
age=18
sex ='male'
getSex =function(){
return this.sex
}
constructor(name,sex){
this.name =name
this.sex=sex
}
}
const p = new Person('alex')
console.log(p.name);
//静态方法
class Person{
constructor(name,sex){
this.name =name
this.sex =sex
}
speak(){
console.log('speak');
}
static speak(){
console.log('人类可以说话');
//this指向类
console.log(this);
}
}
// person.speak = function(){
// console.log(this);
// }
Person.speak()
//静态属性
class Person{
constructor(name){
this.name =name
}
speak(){
console.log('speak');
}
//不要这么写,只是提案,有兼容问题
static version = '1.0'
static getVersion(){
return '1.0'
}
}
const pp = new Person('alex')
console.log(pp.name);
console.log(Person.getVerion);
私有属性和方法
//一般情况下,类的属性和方法都是公开的
class Person{
constructor(name){
this.name = name
}
speak(){
console.log('speak');
}
getName(){
return tshi.name
}
}
const p = new Person('alex')
console.log(p.name);
p.speak()
// 模拟私有属性和方法 _开头表示私有
class Person{
constructor(name){
this._name = name
}
}
//将私有属性和方法移出类
(function(){
let name = ''
class Person{
constructor(username){
name = name
}
}
window.Person = Person
})()
(function(){
const p = new Person('Alex')
console.log(p.name);
console.log(p.getName);
})()
继承
extends
//子类继承父类
class Person{
constructor(name,sex){
this.name = name
this.sex = sex
this.say = function(){
console.log('say');
}
}
speak(){
console.log("speak");
}
static speak(){
console.log("statci");
}
}
//改写记成的属性或方法
class Programmer extends Person{
constructor(name,sex,feature){
//this操作不能放在super前面
super(name,sex)
this.feature =feature
}
//同名覆盖
speak(){
console.log('speak');
}
}
Programmer.version =20
const zs = new Programmer('zs',"男",'光头')
console.log(zs.name);
console.log(zs.sex);
zs.say()
zs.speak()
Programmer.speak()
console.log(Programmer.version);
super
//作为函数调用 代表父类的构造方法,只能用在子类的构造方法中,用在其他地方就会报错
class Person{
constructor(name){
this.name = name
}
}
class Programmer extends Person{
constructor(name,sex){
super(name,sex)
}
}
new Programmer()
//作为对象使用 在构造方法使用
//super代表父类的原型对象Person.prototype,所有定义在父类实例伤的方法或属性,是无法通过super调用的通过super调用父类的方法时,方法内部的this指向当前的子类实例
class Person{
constructor(name){
this.name = name
console.log(this);
}
speak(){
console.log("speak");
console.log(this);
}
}
class Programmer extends Person{
constructor(name,sex){
super(name,sex)
super.speak()
}
speak(){
super.speak()
console.log('pro sp');
}
//在静态方法中使用 指向父类,而不是父类的原型对象
//通过super调用父类的方法时.方法内的this指向当前子类,而不是子类实例
static speak(){
super.speak()
console.log('progerammer speak');
}
}
//使用super的时候,必须显示指定是作为函数还是作为对象使用,否则会报错
class person{
constructor(name){
this.name = name
}
speak(){
console.log("speak");
}
}
class Programmer extends Person{
constructor(name,sex){
super(name,sex)
console.log(super.speak);
}
}
初始Module
Module是什么
//模块:一个一个的局部作用域的代码块
//模块系统需要解决举要问题
//①模块化的问题
//②消除全局变量
//③管理加载顺序
//requireJS seaJS 模块库
Module的两种导入导出
导出的东西可以被导入(import),并访问
//一个模块没有导出,也可以将其导入,仅会执行一边
<script type='module'>
import age from './module.js'
</scrpt>
//一个模块只能有一个exprot default
exprot default age
export和对应的import
//不能随意命名
improt{age}from `./module.js`
//exprot声明或语句
export const age = 18
//或
export {age}
//多个导出
improt{fn,age,className} from'./moudule.js'
export {age,fn,calssName}
//起别名
export {age as ge}
//整体导入 会导入所有输出,包括通过export default导出的
improt * as obj from'./moudule.js'
Module的注意事项
1.模块中,顶层的this指向undefined
2.impott和import()
import命令具有提升效果,会提升到整个模块头部,率先执行
import和export命令只能在模块的顶层,不能在代码块中执行
//导入导出复合写法 (无法在当前模块使用)
export {age}from `./module.js`
//等价于
improt{age}from `./module.js`
Webpack
Webpack是什么
wabpack是静态模块打包器,当webpack处理应用程序时,会将所有这些模块打包成一个或多个文件
webpack可以处理js/css/图片,图标字体等单位
开发过程中存在于本地的js/css/图片/图标字体等文件,就是静态的
动态的内容,webpack没办法处理,只能处理静态的
Webpack初体验
1.初始化项目:npm init
2.安装webpack包:npm install --save-dev webpack-cli@3.3.12 webpack@4.44.1
3.配置webpack
4.编译并测试
Webpack的四个核心概念
entry
//单入口
entry:'./src/index.js',
//多入口
entry:{
main:'./src/index.js'
search:'./src/search.js'
}
output
//单出口
output:{
path:path.resolve(__dirname,'dist'),
filename:'bundle.js'
}
//多出口
output:{
path:path.resolve(__dirname,'dist'),
filename:'[name].js'
}
loader
// loader让webpack能够去处理那些非js文件的模块
// babel-loader
// npm install --save-dev babel-loader@8.1.0 @babel/core@7.11.0 @babel/preset-env@7.11.0