ES6 课堂笔记

article/2025/4/30 11:24:58

ES6

第一章 ECMASript 相关介绍

1.1 什么是 ECMA

ECMA(European Computer Manufacturers Association)中文名称为欧洲计算机制造商协会,这个组织的目标是评估、开发和认可电信和计算机标准。1994 年后该组织改名为 Ecma 国际。

1.2 什么是 ECMAScript

ECMAScript 是由 Ecma 国际通过 ECMA-262 标准化的脚本程序设计语言。

1.3 为什么要学习 ES6

  • ES6 的版本变动内容最多,具有里程碑意义
  • ES6 加入许多新的语法特性,编程实现更简单、高效
  • ES6 是前端发展趋势,就业必备技能

1.4 ES6 兼容性

http://kangax.github.io/compat-table/es6/ 可查看兼容性

第二章 ECMAScript 6 新特性

2.1 let 关键字

特性
  • 变量不能重复声明
  • 块儿级作用域
  • 不存在变量提升(不允许在变量声明之前使用变量)
  • 不影响作用域链
应用场景

​ 以后声明变量使用 let 就对了

2.2 const 关键字

特性
  • 声明必须赋初始值
  • 标识符一般为大写
  • 不允许重复声明
  • 值不允许修改
  • 块儿级作用域
注意

​ 对象属性修改和数组元素变化不会出发 const 错误

应用场景

​ 声明对象类型使用 const,非对象类型声明选择 let

2.3 变量的解构赋值

ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构赋值。

//数组的解构赋值
const arr = ['张学友', '刘德华', '黎明', '郭富城'];
let [zhang, liu, li, guo] = arr;
console.log(zhang); // 张学友//对象的解构赋值
const lin = {name: '林志颖',tags: ['车手', '歌手', '小旋风', '演员'],changge: function () {console.log('我可以唱歌');}
};
let {name, tags} = lin;
console.log(name); // 林志颖
let {cahngge} = lin;
changge(); // 我可以唱歌

2.4 模板字符串

模板字符串(template string)是增强版的字符串,用一对反引号(`)标识

特性
  • 字符串中可以出现换行符
  • 可以使用 ${xxx} 的输出变量

2.5 简化对象写法

ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。

let name = '尚硅谷';
let slogon = '永远追求行业更高标准';
let improve = function () {console.log('可以提高你的技能');
}
//属性和方法简写
let atguigu = {name,slogon,improve,change() {console.log('可以改变你')}
};

2.6 箭头函数

ES6 允许使用「箭头」 => 定义函数。

ES6 允许给函数参数赋初始值

  • 具有默认值的参数,一般靠后
  • 可以与解构赋值结合
注意点
  • 如果形参只有一个,则小括号可以省略
  • 函数体如果只有一条语句,则花括号可以省略,此时 return 必须省略,而且函数的返回值为该条语句的执行结果
  • 箭头函数 this 是静态的,始终指向声明时所在作用域下 this 的值
  • 箭头函数不能作为构造函数实例化
  • 不能使用 arguments
// 通用写法
let fn = (arg1, arg2, arg3) => {return arg1 + arg2 + arg3;
}
// 省略花括号的情况
let fn3 = score => score * 20;
应用场景

适合与 this 无关的回调 定时器、数组的方法回调

不适合与 this 有关的回调 事件回调、对象的方法

2.7 rest 参数

ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments

  • ...args
  • rest参数必须要放到最后
/**
* 作用与 arguments 类似
*/
function add(...args){console.log(args); // [1,2,3,4,5]
}
add(1,2,3,4,5);
/**
* rest 参数必须是最后一个形参
*/
function minus(a,b,...args){console.log(a);		// 100console.log(b);		// 1console.log(args);	// [2,3,4,5,19]
}
minus(100,1,2,3,4,5,19);
应用场景

rest 参数非常适合不定个数参数函数的场景

2.8 spread 运算符

扩展运算符(spread)也是三个点...。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列,对数组进行解包。

应用
  1. 数组的合并

    const arr1 = [1, 2];
    const arr2 = [3, 4];
    // const hebing = arr1.concat(arr2); 原先api函数
    const hebing = [...arr1, ...arr2]
    
  2. 数组的克隆

    const arr1 = [1, 2];
    // 注意是 浅克隆
    const hebing = [...arr1,]
    
  3. 将伪数组转为真正的数组

    const divs = document.querySelectAll('div'); // 伪数组
    const divArr = [...divs]
    

2.9 Symbol

ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型。

特点
  • Symbol 的值是唯一的,用来解决命名冲突的问题
  • Symbol 值不能与其他数据进行运算
  • Symbol 定义的 对象属性 不能使用 for…in 循环遍历 ,但是可以 使用 Reflect.ownKeys 来获取对象的所有键名
// 创建 Symbol
let s = Symbol();
console.log(s, typeof s); // Symbol() "symbol"
let s2 = Symbol('张艺兴'); // 注释作用
let s3 = Symbol('张艺兴');
console.log(s2 === s3); // false
// Symbol.for 创建
let s4 = Symbol.for('张艺兴');
let s5 = Symbol.for('张艺兴');
console.log(s4, typeof s4); // Symbol(张艺兴) "symbol"
console.log(s4 === s5); // true

Symbol['say']: function () {}

内置值

JS 数据类型总结

USONB (you are so niubility)

  • u : undefined
  • s : string Symbol
  • o : object
  • n : null number
  • b : boolean

2.10 迭代器

遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作。

  • ES6 创造了一种新的遍历命令 for…of 循环,Iterator 接口主要供 for…of 消费

    // 声明一个数组
    const xiyou = ['1', '2', '3', '4'];// 使用 for...of 遍历数组
    for (const v of xiyou) {console.log(v);
    }
    
  • 原生具备 iterator 接口的数据(可用 for of 遍历)

  • Array

  • Arguments

  • Set

  • Map

  • String

  • TypedArray

  • NodeList

  • 工作原理

    • 创建一个指针对象,指向当前数据结构的起始位置
    • 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员
    • 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员
    • 每调用 next 方法返回一个包含 value 和 done 属性的对象
    let iterator = xiyou[Symbol.iterator]();// 调用对象的 next 方法
    console.log(iterator.next());
    console.log(iterator.next());
    console.log(iterator.next());
    console.log(iterator.next());
    console.log(iterator.next());
    

    运行结果:
    请添加图片描述

应用场景

需要自定义遍历数据的时候,要想到迭代器。

自定义遍历对象
// 声明一个对象
const banji = {name: '终极一班',stus: ['xiaoming','xiaoning','xiaotian','knight'],[Symbol.iterator]() {// 索引变量let index = 0;let _this = this;return {next: function () {if (index < _this.stus.length) {const result = {value: _this.stus[index], done: false}// 下表自增index++;// 返回结果return result} else {return {value: undefined, done: true}}}}}
}// 遍历这个对象
for (const v of banji) {console.log(v);
}

2.11 生成器

生成器函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同,起其实就是一个特殊的函数。

// yield 函数代码的分隔符
function * gen() {// console.log(111);yield '一只没有耳朵';// console.log(222);yield '一只没有尾巴';// console.log(333);yield '真奇怪';// console.log(444);
}let iterator = gen();
// 调用 next() 方法才会执行方法
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());for (const v of gen()) {console.log(v);
}

运行截图:

生成器函数参数
function * gen(arg) {console.log(arg);let one = yield '一只没有耳朵';console.log(one);let two = yield '一只没有尾巴';console.log(two);let three = yield '真奇怪';console.log(three);
}let iterator = gen('AAA');
// 调用 next() 方法才会执行方法
console.log(iterator.next());
console.log(iterator.next('BBB'));
console.log(iterator.next('CCC'));
console.log(iterator.next('DDD'));

运行截图:
在这里插入图片描述

实例

2.12 Promise

Promise 是 ES6 引入的异步编程的新解决方案。语法上 Promise 是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。

Promise 构造方法

const promise = new Promise(function(resolve, reject) {}

// 实例化 Promise 对象
const p = new Promise(function(resolve, reject) {setTimeout(function () {// let data = '数据库中的用户数据'// resolve(data); // 调用 then 中第一个方法let err = '数据读取失败';reject(err); // 调用 then 中第二个方法}, 1000);
});// 调用 Promise 对象的 then 方法
p.then(function (value) {console.log(value); // 数据库中的用户数据
}, function (reason) {console.log(reason); // 数据读取失败
})
Promise 读取文件
// 引入 fs 模块
const fs = require('fs');const p = new Promise(function (resolve, reject) {fs.readFile('./resources/为学.md', 'utf8', (err, data) => {if (err) reject(err);// 如果成功resolve(data);})
})p.then(function (value) {console.log(value);
}, function (reason) {console.log('读取失败');
})
Promise 封装 AJAX
// 接口地址 http://api.apiopen.top/getJokeconst p = new Promise(function (resolve, reject) {// 1. 创建对象const xhr = new XMLHttpRequest();// 2. 初始化xhr.open('GET', 'https://api.apiopen.top/getJoke');// 3. 发送xhr.send();// 4. 绑定事件,处理响应结果xhr.onreadystatechange = function () {if (xhr.readyState === 4) {if (xhr.status >= 200 && xhr.status < 300) {resolve(xhr.response)} else {reject()}}}
})// 指定回调
p.then(function (value) {console.log(value);
}, function (reason) {console.log('获取失败');
})
Promise.prototype.then
// 创建 promise 对象
const p = new Promise((resolve, reject) => {setTimeout(() => {resolve('用户数据');// reject('出错啦');}, 1000);
});// 调用 then 方法  then方法的返回结果是 Promise 对象,对象状态又回调函数的执行结果决定
// 1. 如果回调函数中返回的结果是一个 非Promise 类型的数据,状态为成功,返回值为对象那个的成功值
const result = p.then(value => {console.log(value);// 1. 非 Promise 类型的数据// return 123;// 2. 是 Promise 对象// return new Promise((resolve, reject) => {//   // resolve('ok');//   reject('出错')// })// 3. 抛出错误// throw new Error('出错啦')
}, reason => {console.warn(reason);
});
console.log(result);
链式调用
// 链式调用 可以避免回调地狱的形成
p.then(value=>{},reason=>{}).then(value=>{})

另外,then 方法中的两个方法 不一定需要全有

案例-读取多个文件
// 引入 fs 模块
const fs = require('fs');// 之前的方法 - 回调地狱
// fs.readFile('./resources/为学.md', 'utf8', (err, data1) => {
//   fs.readFile('./resources/插秧诗.md', 'utf8', (err, data2) => {
//     fs.readFile('./resources/观书有感.md', 'utf8', (err, data3) => {
//       let result = data1 + '\r\n' + data2 + '\r\n' + data3;
//       console.log(result);
//     })
//   })
// })// 使用 Promise 实现
const p = new Promise((resolve, reject) => {fs.readFile('./resources/为学.md', 'utf8', (err, data) => {resolve(data);})
})p.then(value => {return new Promise((resolve, reject) => {fs.readFile('./resources/插秧诗.md', 'utf8', (err, data) => {resolve([value, data]);})})
}).then(value => {return new Promise((resolve, reject) => {fs.readFile('./resources/观书有感.md', 'utf8', (err, data) => {value.push(data);resolve(value);})})
}).then(value => {console.log(value.join('\r\n'));
})
Promise catch 方法

不用不影响开发,catch 的作用只是简化,可以只写后面错误的函数,不需要写前面的。

const p = new Promise((resolve, reject) => {setTimeout(() => {// 设置 p 对象的状态为失败,并设置失败的值reject('出错啦!')}, 1000);
})p.then(value => {}, reason => {console.error(reason);
})p.catch(reason => {console.warn(reason);
})

2.13 Set

ES6 提供了新的数据结构 Set(集合)。

它类似于数组,但成员的值都是唯一的,集合实现了 iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历。

属性&方法
  • size 返回集合的元素个数
  • add 增加一个新元素,返回当前集合
  • delete 删除元素,返回 boolean 值
  • has 检测集合中是否包含某个元素,返回 boolean 值
  • clear 清空集合,返回 undefined
// 声明一个 Set
let s = new Set();
let s2 = new Set(['大事儿', '小事儿', '好事儿', '坏事儿', '小事儿']);
console.log(s, typeof s);
console.log(s2); // 自动去重 {"大事儿", "小事儿", "好事儿", "坏事儿"}// 元素的个数
console.log(s2.size); // 4
// 添加新的元素
s2.add('喜事儿');
console.log(s2); // {"大事儿", "小事儿", "好事儿", "坏事儿", "喜事儿"}
// 删除元素
s2.delete('坏事儿');
console.log(s2); // {"大事儿", "小事儿", "好事儿", "喜事儿"}
// 检测
console.log(s2.has('好事儿')); // true
// 清空
s2.clear();
console.log(s2); // {}// 也可实现 for...of 遍历
for (const v of s2) {console.log(v);
}
Set 集合实践
var arr = [1,2,3,4,5,4,3,2,1];
// 1. 数组去重
// let result = [...new Set(arr)];
// console.log(result);
// 2. 交集
let arr2 = [4,5,6,5,6];
// let result = [...new Set(arr)].filter(item => {
//   let s2 = new Set(arr2);
//   if (s2.has(item)) {
//     return true;
//   } else {
//     return false;
//   }
// })
// 简化
let result = [...new Set(arr)].filter(item => new Set(arr2).has(item))
console.log(result); // [4, 5]// 3. 并集
let union = [...new Set([...arr, ...arr2])]
console.log(union);  // [1, 2, 3, 4, 5, 6]// 4. 差集
let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item)))
console.log(diff);   // [1, 2, 3]

2.14 Map

ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。但是“键”
的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map 也实现了iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历。

属性&方法
  • size 返回 Map 的元素个数
  • add 增加一个新元素,返回当前 Map
  • get 返回键名对象的键值
  • has 检测 Map 中是否包含某个元素,返回 boolean 值
  • clear 清空集合,返回 undefined
// 声明 Map
let m = new Map();// 添加元素
m.set('name', '张艺兴')
m.set('change', function () {console.log('张艺兴是最帅的');
})
let key = {school : 'AgoniLay'
}
m.set(key, ['北京', '上海', '深圳'])// size
console.log(m.size); // 3// 删除
m.delete('name')// 获取
// console.log(m.get('change'));
console.log(m.get(key)); // ["北京", "上海", "深圳"]// 清空
// m.clear();// 遍历
for (const v of m) {console.log(v);
}console.log(m);

2.15 Class 类

ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对
象的模板。通过 class 关键字,可以定义类。基本上,ES6 的 class 可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。

知识点
  • class 声明类
  • constructor 定义构造函数初始化
  • extends 继承父类
  • super 调用父级构造方法
  • static 定义静态方法和属性
  • 父类方法可以重写
ES5 方法
// ES5
// 手机
function Phone(brand, price) {this.brand = brand;this.price = price;
}// 添加方法
Phone.prototype.call = function () {console.log('我可以打电话');
}// 实例化对象
let huawei = new Phone('华为', 5999);console.log(huawei);
// huawei.call();
ES6 class
class Shouji {// 构造方法 名字不能修改constructor (brand, price) {this.brand = brand;this.price = price;}// 方法必须使用该语法,不能使用 ES5 的对象完整形式call () {console.log('我可以打电话');}
}let onePlus = new Shouji('1+', 1999);
console.log(onePlus);
静态成员
class Phone {// 静态属性static name = '手机';
static change = function () {console.log('我可以改变世界');
};
}let nokia = new Phone();
console.log(nokia.name); // undefined
console.log(Phone.name); // 手机
类继承
class Phone {// 构造方法constructor (brand, price) {this.brand = brand;this.price = price;}// 父类的成员属性call () {console.log('我可以打电话');}
}class SmartPhone extends Phone {// 构造方法constructor (brand, price, color, size) {super(brand, price);this.color = color;this.size = size;}photo () {console.log('拍照');}playGame () {console.log('打游戏');}
}const xiaomi = new SmartPhone('小米', 799, '黑色', '4.7inch');
console.log(xiaomi);
xiaomi.call();
xiaomi.photo();
xiaomi.playGame();

子类可以进行对父类方法的重写

注:但是不能通过super()调用父类重名方法

set 和 get

获取时,触发 get 方法

修改赋值时,触发 set 方法

注:set 方法必须有一个参数

class Phone {get price () {console.log('价格属性被读取了');return 111}set price (newV) {console.log('价格属性被修改了');}
}// 实例化对象
let s = new Phone();
console.log(s.price); // 111	// 触发 get
s.price = 'free';				// 触发 set

2.16 数值扩展

Number.EPSILON

Number.EPSILON 是 JavaScript 表示的最小精度 ε

EPSILON属性的值接近于:2.2204460492503130808472633361816E-16

console.log(0.1 + 0.2 == 0.3); 		// false
function equal(a, b) {if (Math.abs(a - b) < Number.EPSILON) {return true} else {return false}
}
console.log(equal(0.1 + 0.2, 0.3));	// true
二进制和八进制

ES6 提供了二进制和八进制数值的新的写法,分别用前缀 0b 和 0o 表示。

let b = 0b1010;		// 二进制
let b = 0o777;		// 八进制let d = 100;		// 十进制
let x = 0xff;		// 十六进制
Number.isFinite()

用来检查一个数值是否为有限的,返回 boolean

Number.isNaN()

用来检查一个值是否为 NaN,返回 boolean

Number.parseInt() & Number.parseFloat()

移植到了 Number 对象下,使用不变,(截取整数,截取浮点数)

Number.isInteger()

用来判断一个数值是否为整数, 返回 boolean

Math.trunc()

将数字的小数部分抹掉

Math.sign()

判断一个数是 正数(1) 负数(-1) 还是 0(0) 括号内为相应的返回值

2.17 对象方法

Object.is(a,b)

判断两个值是否完全相等

与全等号 === 区别:

console.log(Object.is(NaN, NaN)); // true
console.log(NaN === NaN); 		  // false
Object.assign(a,b)

对象的合并,后面的将前面的覆盖掉

可以用于更新对象

const config1 = {host: 'localhost',prot: 3306,name: 'root',pass: 'root',test: 'test'
}
const config2 = {host: 'http://www.baidu.com',prot: 33060,name: 'AgoniLay',pass: '020316'
}console.log(Object.assign(config1, config2));
/*host: "http://www.baidu.com"name: "AgoniLay"pass: "020316"prot: 33060test: "test"
*/
Object.setPrototypeof & Object.getPrototypeof

设置原型对象,一般不使用

console.log(Object.assign(config1, config2));
// Object.setPrototypeof  Object.getPrototypeof
const school = {name: '张艺兴'
}
const cities = {xiaoqu: ['北京', '上海', '深圳']
}Object.setPrototypeOf(school, cities)
console.log(Object.getPrototypeOf(school));
console.log(school);

2.18 模块化

概述

模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。

好处
  • 防止命名冲突
  • 代码复用
  • 高维护性
语法

模块功能主要由两个命令构成:export 和 import

  • export 命令用于规定模块的对外接口
  • import 命令用于输入其他模块提供的功能

模块化规范

浏览器端
  1. AMD:Request.js (http://www.requirejs.cn/)
  2. CMD:Sea.js (https://seajs.github.io/seajs/docs/)
服务器端
  • CommonJS:NodeJS
    1. 模块分为 单文件模块 与 包
    2. 模块成员导出:module.exports 和 exports
    3. 模块成员导入:require(‘模块标识符’)

2.19 大一统的模块化规范 - ES6模块化

是 浏览器端 与 服务器端 通用的模块化开发规范

  • 每一个 js 文件都是一个独立的模块
  • 导入模块成员使用 import 关键字
  • 暴露模块成员使用 export 关键字

Node.js 中 babel 体验 ES6 模块化

步骤
  1. 安装工具

    npm install --save-dev @babel/core @babel/cli @babel/preset-env @babel/node
    
    npm install --save @babel/polyfill
    
  2. 根目录下新建 babel.config.js 文件 写入:

    const presets = [["@babel/env", {targets: {edge: "17",firefox: "60",chrome: "67",safari: "11.1"}}]
    ]module.exports = { presets }
    
  3. 执行代码

    npx babel-node index.js
    

基本语法

默认导出 与 默认导入
  • 默认导出:export default 默认导出的成员
  • 默认导入:import 接收名称 from '模块标识符/路径'

注意点:

  1. 在每个模块中,只允许使用唯一的一次 export default,否则会报错
  2. 在模块中如果没有默认导出,那么将会 是一个空对象 {}
按需导出 与 按需导入
  • 按需导出:export let s1 = 10
  • 按需导入:import { s1 } from '模块标识符/路径'

注意点:

  1. 在一个模块中,可以使用多次按需导出
直接导入并执行模块代码

import '模块标识符/路径'

直接执行代码,没有导出。

2.20 webpack

当前 Web开发 面临的困境:

  • 文件以来关系错综复杂
  • 静态资源请求效率低
  • 模块化支持不友好
  • 浏览器对高级 JavaScript 特性兼容程度较低

webpack 概述

webpack 是一个流行的前端项目构建工具(打包工具),可以解决当前 web 开发中所面临的困境。

提供了友好的模块化支持,以及代码压缩混淆处理 js 兼容问题性能优化等强大的功能,提高了开发效率和项目的可维护性。

基本使用

1.创建列表隔行变色项目
  1. 创建项目空白目录,并运行 npm init -y 命令,进行初始化包管理配置文件 package.json
  2. 新建 src 源代码目录
  3. 新建 src -> index.html 首页
  4. 初始化首页基本结构
  5. 运行 npm install jquery -S 命令, 安装 jQuery
  6. 通过模块化的形式,实现列表隔行变色效果
2. 在项目中安装和配置 webpack
  1. 运行 npm insatll webpack webpack-cli -D 命令,安装 webpack 相关的包

  2. 在项目根目录中,创建名为 webpack.config.js 的 webpack 配置文件

  3. 在 webpack 的配置文件中,初始化如下基本配置:

    module.exports = {mode: 'development' // mode 用来指定构建模式
    }
    

    注意:开发阶段 mode 值一般设置为 development ,上线时才设置成 production (会进行压缩与混淆,转换时间会更长)

  4. 在 package.json 配置文件中的 scripts 节点下,新增 dev 脚本如下:

    "scripts": {"dev": "webpack" // script 节点下的脚本,可以通过 npm run 执行
    }
    
  5. 在终端中运行 npm run dev 命令,启动 webpack 进行项目打包。

注意:主页面中导入的应该为打包生成后的 dist 文件夹下的 js 文件

3. 配置打包的入口和出口

webpack 的 4.x 版本中默认约定:

  • 打包的 入口文件 为 src -> index.js
  • 打包的 输出文件 为 dist -> main.js

修改打包的入口(entry)和出口(output),可以在 webpack.config.js 中增加如下配置:

const path = require('path')module.exports = {entry: path.join(__dirname, './src/index.js'), // 打包入口文件的路径output: {path: path.join(__dirname, './dist'), // 输出文件的存放路径filename: 'bundle.js' // 输出文件的名称}
}
4. 配置 webpack 的自动打包功能
  1. 运行 npm install webpack-dev-server -D 命令,安装支持项目自动打包的工具

  2. 修改 package.json -> scripts 中的 dev 命令如下:

    "scripts": {"dev": "webpack server"
    },
    
  3. 将 src -> index.html 中,script 脚本的引用路径,修改为 “/bundle.js”

  4. 运行 npm run dev 命令,重新进行打包

  5. 在浏览器中访问 http://localhost:8080 地址,查看自动打包效果。

5. 配置 html-webpack-plugin 生成预览页面
  1. 运行 npm install html-webpack-plugin -D 命令,安装生成预览页面的插件

  2. 修改 webpack.config.js 文件头部区域,添加如下配置信息:

    const HtmlWebpackPlugin = require('html-webpack-plugin')const htmlPlugin = new HtmlWebpackPlugin({template: './src/index.html',filename: 'index.html'
    })
    
  3. 修改 webpack.config.js 文件中向外暴露的配置对象,新增如下配置节点:

    module.exports = {plugins: [ htmlPlugin ] // plugins 数组时 webpack 打包期间会用到的一些插件列表
    }
    
6. 配置自动打包相关的参数
  • –open 打包完成自动打开浏览器页面
  • –host 配置 IP 地址
  • –port 配置端口
"scripts": {"dev": "webpack server --open --host 127.0.0.1 --port 8080"
},

webpack 中的加载器

报错解决

控制台报错:

DevTools failed to load SourceMap: Could not load content for webpack:///node_modules/sockjs-client/

解决:

webpack.config.js 中配置一项

module.exports = {devtool: 'inline-source-map'
}
通过 loader 打包非 js 模块
  • less-loader 可以打包处理 .less 相关的文件
  • sass-loader 可以打包处理 .scss 相关的文件
  • url-loader 可以打包处理 css 中与 url 路径相关的文件
基本使用
1. 打包处理 css 文件
  1. 运行 npm install style-loader css-loader -D 命令,安装处理 css 文件的 loader

  2. 在 webpack.config.js 的 module -> rules 数组中,添加 loader 规则如下:

    module: {rules: [{test: /\.css$/, use: ['style-loader', 'css-loader']}]
    }
    

    其中,test 表示匹配的文件类型,use 表示对应要调用的 loader

注意:

  • use 数组中指定的 loader 顺序是固定的
  • 多个 loader 的调用顺序是:从后往前调用
2. 打包处理 less 文件
  1. 运行 npm i less-loader less -D 命令,

  2. 在 webpack.config.js 的 modeule -> rules 数组中,添加 loader 规则如下:

    module: {rules: [{test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader']}]
    }
    
3. 打包处理 scss 文件
  1. 运行 npm i sass-loader node-sass -D 命令,

    运行不通使用:

    1. 首先删除 node_modules 中的 sass-loader 和 node-sass 目录

    2. 配置淘宝镜像

      npm install -g cnpm --registry=https://registry.npm.taobao.org

    3. 用 cnpm 重新安装一次
      cnpm install node-sass -D
      cnpm install sass-loader -D

  2. 在 webpack.config.js 的 modeule -> rules 数组中,添加 loader 规则如下:

    module: {rules: [{test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader']}]
    }
    
4. 配置 postCSS 自动添加 css 的兼容前缀
  1. 运行 npm i postcss-loader autoprefixer -D 命令,

  2. 在项目根目录中创建 postcss 的配置文件 postcss.config.js,并初始化如下配置:

    // 导入自动添加前缀的插件
    const autoprefixer = require('autoprefixer')module.exports = {plugins: [ autoprefixer ] // 挂载插件
    }
    
  3. 在 webpack.config.js 的 modeule -> rules 数组中,修改 css 的 loader 规则如下:

    module: {rules: [{test: /\.css$/, use: ['style-loader', 'css-loader', 'postcss-loader']}]
    }
    
5. 打包样式表中的图片和字体文件
  1. 运行 npm i url-loader file-loader -D 命令,

  2. 在 webpack.config.js 的 modeule -> rules 数组中,添加 loader 规则如下:

    module: {rules: [{ test: /\.jpg|png|gif|bmp|ttf|eot|svg|woff|woff2$/, use: 'url-loader?limit=32417' },]
    }
    

    注:? 后 limit参数是文件的大小(单位是字节),小于此大小 才会编译为 base64 格式

6. 打包处理 js 文件中的高级语法
  1. 运行

    npm i babel-loader @babel/core @babel/runtime -D
    

    命令,安装 babel 转换器相关的包

  2. 运行

    npm i @babel/preset-env @babel/plugin-transform-runtime @babel/plugin-proposal-class-properties -D
    

    命令,安装babel语法插件相关的包

  3. 在项目根目录下,创建 babel 配置文件 babel.config.js 并初始化基本配置如下:

    module.exports = {presets: ['@babel/env'],plugins: ['@babel/plugin-transform-rutime', '@babel/plugin-proposal-class-properties']
    }
    
  4. 在 webpack.config.js 的 modeule -> rules 数组中,添加 loader 规则如下:

    // exclude 为排除项,表示 babel-loader 不需要处理 node_modules 中的 js 文件
    module: {rules: [{ test: /\.js$/, use: 'babel-loader', exclude: /node_modules/ }]
    }
    

    npm 安装不了,就用 cnpm 安装

7. 配置 vue 组件的加载器
  1. 运行 npm i vue-loader vue-template-compiler -D 命令,

  2. 在 webpack.config.js 的 modeule -> rules 数组中,添加 loader 规则如下:

    const VueLoaderPlugin = require('vue-loader/lib/plugin')module.exports = {module: {rules: [{ test: /\.vue$/, use: 'vue-loader' }]},plugin: [new VueLoaderPlugin()]
    }
    

webpack 中使用 Vue

  1. 运行 npm i vue -S 安装 vue
  2. 在 src -> index.js 入口文件中,通过 ipmort Vue from 'vue' 来导入 vue 构造函数
  3. 创建 vue 的实例对象,并且要控制的 el 区域
  4. 通过 render 函数渲染 App 根组件

index.js

import Vue from 'vue'
// 导入 单文件组件
import App from './components/App.vue'const vm = new Vue({el: '#app',render: h => h(App)
})

报错处理

Error: Cannot find module ‘@babel/preset-preset.env’

解决:

将 babel.config.js 配置文件中的 preset-env ,改为 env

webpack 打包发布

上线之前需要通过 webpack 将应用进行整体打包,可以通过 package.json 文件配置打包命令:

{"scripts": {"build": "webpack"},
}

第三章 ES7 新特性

3.1 Array.prototype.includes

Includes 方法用来检测数组中是否包含某个元素,返回 boolean 类型值

3.2 指数运算符

在 ES7 中引入指数运算符「**」,用来实现幂运算,功能与 Math.pow 结果相同

console.log(2 ** 10); // 1024
console.log(Math.pow(2, 10)); // 1024

http://chatgpt.dhexx.cn/article/S6iUCSJw.shtml

相关文章

深度学习:智能时代的核心驱动力量

内容简介 科技巨头纷纷拥抱学习,自动驾驶、AI、语音识别、图像识别、智能翻译以及震惊世界的 AlphaGo,背后都是学习在发挥的作用。学习是人工智能从概念到繁荣得以实现的主流技术。经过学习训练的计算机,不再被动按照指令运转,而是像自然进化的生命那样,开始自主地从经验中…

林家栋这三十年:深获万梓良、刘德华赏识,靠配角成为影帝

https://www.toutiao.com/a6703796759279174155/ 文 | 王珍一 编辑 | 李小白 很少有演员在成为影帝之后&#xff0c;还能静心的做着配角&#xff0c;林家栋做到了。 从香港无线电视艺员训练班的艺员到成为影帝&#xff0c;林家栋用了30年。 在这漫长的30年里&#xff0c;他静…

新特效火爆抖音!各路神仙齐唱《蚂蚁呀嘿》,网友:短短几秒需一生来治愈

金磊 杨净 发自 凹非寺 量子位 报道 | 公众号 QbitAI 当互联网大佬们集体唱歌&#xff0c;会擦出怎样的火花&#xff1f; 现在&#xff0c;火爆抖音的AI特效&#xff0c;一键就可以实现梦幻联动。 瞧&#xff01;马云、马化腾、马斯克等大佬们&#xff0c;正在集体演唱神曲《蚂…

《猩球黎明》首曝海报

2019独角兽企业重金招聘Python工程师标准>>> 昨日刚刚宣布将档期提至2014年7月11日的《猩球黎明》(Dawn of the Planet of the Apes)&#xff0c;在今日发布了首批角色海报&#xff0c;四张各色的猩猩脸孔&#xff0c;像人类的军人一般在战前在脸上图油彩&#xff0…

知名演员从北大毕业!学位论文让网友直呼:请收下我的膝盖!

来源&#xff1a;广州日报 编辑&#xff1a;双一流高校 近日&#xff0c;49岁香港男艺人马浚伟发布微博称&#xff0c;自己已通过北京大学光华管理学院硕士研究生学位论文答辩&#xff0c;顺利毕业。 相关的一则话题达到了1200万的阅读量&#xff0c;超7000名网友参与讨论。 两…

【腾讯圣诞晚会TEG节目】这里的黎明静悄悄

2018腾讯圣诞晚会全新出发 梦里好成功 如果你什么都没有&#xff0c;至少得有点想象力。 我们今年的男主角郝成功&#xff0c;就是一直生活在想象的美好中。他每天乘坐价值上亿的交通工具&#xff08;地铁&#xff09;上下班&#xff0c;在五星级餐厅享用奢华早餐&#xff08;茶…

中国武打演员大全

1.李小龙&#xff0c;精湛的武功。发千斤于一点&#xff0c;冲极限于苦炼&#xff0c;集所有搏击武功之大成&#xff0c;创造截拳道&#xff0c;使无法为有法&#xff0c;以无限为有限。威震搏击界&#xff0c;并首次将“功夫”做为影片的中心构成因素&#xff0c;发中国功夫片…

Oracle 主外键约束

一 主键&#xff08;Primary Key&#xff09; 1 一个表只能有一个主键&#xff0c;作为主键的列具有唯一&#xff08;unique&#xff09;和非空约束(not null)&#xff1b; 2 对列创建了主键约束的同时&#xff0c;会自动对列创建一个索引&#xff1b; 3 创建表时创建主键两种…

mysql中的外键约束_MySQL外键约束

在本教程中&#xff0c;您将了解MySQL外键(foreign key)以及如何在MySQL中创建&#xff0c;添加和删除外键约束。 MySQL外键简介 外键表示一个表中的一个字段被另一个表中的一个字段引用。外键对相关表中的数据造成了限制&#xff0c;使MySQL能够保持参照完整性。 下面来看看示…

MySQL——外键约束

设置外键约束(FOREIGN KEY, FK ) MySQL外键约束是表的一个特殊字段&#xff0c;经常与外键约束一起使用。对于两个具有关联关系的表而言&#xff0c;相关字段中主键所在表称为主表&#xff08;父表&#xff09;&#xff0c;外键所在表称为从表&#xff08;子表&#xff09;。 …

mysql数据库 外键约束

外部关键字 在以后我们统一将外部关键字叫做外键&#xff0c;外键就是另一张表中的主键。 问&#xff1a;外键有啥用啊&#xff1f;答&#xff1a;外键的主要作用就是保持数据的一致性&#xff0c;完整性。 再问&#xff1a;怎么保证的呢&#xff1f;答&#xff1a;看图。 如…

为啥禁用外键约束

【阿里JAVA规范】 &#xff1a;不得使用外键与级联&#xff0c;一切外键概念必须在应用层解决 阿里巴巴为什么这么规定&#xff1f; 1.每次做DELETE 或者UPDATE都必须考虑外键约束&#xff0c;会导致开发的时候很痛苦,测试数据极为不方便&#xff0c;也就是说插入一条主记录的…

Mysql外键约束怎么删除

记录一下碰到的问题。由于我是使用PowerDesigner来建mysql物理模型的&#xff0c;为了表与表之间的关系更加清楚&#xff0c;我给他们连线了。之后我就用它生成的SQL语句在navicat把表建出来&#xff0c;我看见没问题就直接用了&#xff0c;毕竟初学者嘛&#xff0c;嘿嘿。 到我…

mysql怎么写主外键_mysql主外键约束怎么写?

mysql主键约束的写法:“CREATE TABLE 表名(字段名 数据类型 PRIMARY KEY)”;mysql外键约束的写法:“CREATE TABLE 表名(FOREIGN KEY 字段名 REFERENCES 主表名 主键列)”。 mysql主键约束 主键(PRIMARY KEY)的完整称呼是“主键约束”,是 MySQL 中使用最为频繁的约束。一般情…

mysql外键约束怎么写_mysql外键约束怎么写

mysql外键约束的写法:【[CONSTRAINT ] FOREIGN KEY 字段名 REFERENCES 主键列1】。外键约束是表的一个特殊字段,经常与主键约束一起使用。 在 CREATE TABLE 语句中,通过 FOREIGN KEY 关键字来指定外键。 (推荐学习:mysql教程) 具体的语法格式如下:[CONSTRAINT ] FOREIGN K…

选型必看:RabbitMQ 七战 Kafka,差异立现

点击上方 "程序员小乐"关注, 星标或置顶一起成长 每天凌晨00点00分, 第一时间与你相约 每日英文 Sometimes you just have to pick yourself up and carry on. 有时候&#xff0c;你只能自己振作起来&#xff0c;继续努力下去。 每日掏心话 夜晚想要矫情的时候&#…

小程序上传发布版本配置以及登录报错

钉钉小程序编写完之后需要上传先附上操作地址https://oa.dingtalk.com/?redirecthttp%3A%2F%2Foa.dingtalk.com%2Fomp%2Fapi%2Fmicro_app%2Fadmin%2Flanding%3Fcorpid%3Dopen-dev.dingtalk.com%26redirect_url%3Dhttp%3A%2F%2Fopen-dev.dingtalk.com%2F#/login。 首先需要确认…

2021-08-25

omp版本swan linux netcdf export CCgcc export CXXg export FCgfortran export F77gfortran export F90gfortran perl switch.pl -unix -pun -netcdf make config nf –config --all 查看netcdf fortran库安装位置 Fflags 写在FLAGS_SER后面 Flibs 写在else Libs_ser后面 –…

【小技巧】如何安装下载MATLAB最新的工具箱

小伙伴们&#xff0c;在使用matlab的时候&#xff0c;经常会遇到某些函数无法找到而导致程序报错&#xff0c;通常情况&#xff0c;一般是由于该函数是MATLAB一些工具箱中的函数&#xff0c;而原始版本的MATLAB是没有这个工具箱的&#xff0c;所以导致报错。那么如何查看当前版…

数字化时代,如何做好用户体验与应用性能管理

引言 随着数字化时代的到来&#xff0c;各个行业的应用系统从传统私有化部署逐渐转向公有云、行业云、微服务&#xff0c;这种变迁给运维部门和应用部门均带来了较大的挑战。基于当前企业 IT 运维均为多部门负责&#xff0c;且使用多种运维工具&#xff0c;因此&#xff0c;当…