目录
前言
一、ECMASript相关介绍
1.什么是ECMA
2. 什么是ECMAScript
3. 什么是ECMA-262
4. ES6兼容性
二、ES6-变量声明
1.let
2.const(定义常量)
3. 变量的解构赋值
4. 模板字符串
5. 对象的简化写法
6. 箭头函数以及声明特点
7. 箭头函数的实践与应用场景
8. 函数参数的默认值设置
9. rest参数
10.扩展运算符
11.Symbol
11.1 Symbol的介绍与创建
11.2 .对象添加Symbol类型的属性
11.3 Symbol内置属性
12.迭代器的介绍
13. 生成器
13.1 生成器函数的声明与调用
13.2 生成器函数参数
13.3 生成器函数实例
14. Promise
14.1 Promise介绍与基本使用
15. Set
16. Map
17. Class类
17.1 初体验
17.2 class静态成员static
17.3 构造函数继承
17.4 class中getter和setter设置
18. ES6数值扩展
19. 对象方法扩展
20. 模块化
20.1 模块化开发的好处
20.2 ES6模块化语法
21. babel对ES6模块化代码转换
22. ES6模块化引入NPM包
三、ES7新特性
1. Array.prototype.includes
2. 指数操作符
四、ES8新特性
1. async和await
1.1 async
1.2 await表达式
2. ES8对象方法扩展
五、ES9
1. 扩展运算符和rest参数
2. 正则扩展--命名捕获分组
3. 正则扩展--反向断言
4. 正则扩展--dotAll模式
六、ES10
1. Object.fromEntries()
2. 字符串扩展方法
3. 数组方法扩展
4. Symbol.prototype.description
七、ES11
1. 私有属性
2. Promise.allSettled
3. Strinprototype.matchAll()--得到正则批量匹配的结果
4. 可选链操作符 (?.)
5. 动态import
6. BIgInt类型
7. globalThis--始终指向全局对象
八、参考资料
课程介绍
ECMA(European Computer Manufacturers Association)中文名称为欧洲计算机制造商协会。这个组织的目标是评估、开发和认可电信和计算机标准。1944年后该组织改名为Ecma国际
ECMAScript是由Ecma国际通过ECMA-262标准化的脚本程序设计语言。
Ecma国际制定了许多标准,而ECMA-262只是其中的一种,所有的标准列表查看
ECMA-262 - Ecma International
ECMAScript 6 compatibility table可查看兼容性
let a;
let b,c,d;
let e = 100;
let f = 520,g = "相思" , h = [];
特征
1. 变量不能重复声明;
2. 块级作用域、全局、函数、eval
例如:if else while for
{
let id = "超爱蓝莓汁"
}
console.log(id); //报错:id is not defined
3. 不存在变量提升
4. 不影响作用域链
{
let id = "超爱蓝莓汁";
function fn(){
console.log(id);
}
fn()
}
5. 案例
点击切换颜色
const ID = "超爱蓝莓汁";
特征
1. 一定要赋初始值;
const A;(报错)
2. 一般常量用大写字母(潜规则)
const ID = "超爱蓝莓汁";
3. 常量的值不能修改
ID = "超能陆战队"(报错)
4. 块级作用域、全局、函数、eval
例如:if else while for
{
let ID= "超爱蓝莓汁"
}
console.log(ID); (报错)
5. 对于数组和对象的元素修改,不算做对敞亮的修改,不会报错
const XIYOUJI = ["孙悟空", "猪八戒", "沙悟净"]
XIYOUJI.push("唐玄奘")
// ES6允许按照一定模式从数组和对象中提取值,对变量进行赋值,这被称为解构赋值
// 1. 数组的解构赋值
const FAMILY = ["萨姗家族", "佐汌家族", "斯奈家族", "雪之一族"]
let [萨姗, 佐汌, 斯奈, 雪] = FAMILY
console.log(萨姗, 佐汌, 斯奈, 雪); //萨姗家族 佐汌家族 斯奈家族 雪之一族
// 2. 对象的解构赋值
const HAIINYAN = {
name: "海琴烟(冰公主)",
age: 19,
ability: function () {
console.log("可以和动物交流");
}
}
let { name, age, ability } = HAIINYAN;
console.log(name, age) //海琴烟(冰公主) 19
ability() //可以和动物交流
// ES6 引入新的声明字符串的方式:反引号:``
// 1. 声明
let str =`我也是字符串`
console.log(typeof str,str);//string 我也是字符串
// 特性
// 1. 内容中可以直接出现换行符
let str1 = `
- 郭德纲
- 岳云鹏
- 郭麒麟
`
// 2. 变量拼接
let lovest = "郭麒麟";
let out = `${lovest}是三个人中最年轻的`
console.log(out); //郭麒麟是三个人中最年轻的
// ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法,这样的写法更简洁
// 1. 属性名和变量一样时可以如下简写
// 2. 函数可以去掉冒号和function:如:music(){}
let author = "wlop";
let work = function(){
console.log("鬼刀");
}
const CHARACTER = {
author,
work,
music(){
console.log("GHOSTBLADE");
}
}
console.log(CHARACTER);//{author: 'wlop', work: ƒ, music: ƒ}
// ES6 允许使用【箭头】(=>)定义函数
// 1. 声明一个函数
let fn = (a, b) => {
return a + b
}
let result = fn(1, 2)
console.log(result);//3
特性
// 1. this是静态的,this始终指向函数声明时所在作用域下的this的值
function getName() {
console.log(this.name);
}
let getName1 = () => {
console.log(this.name);
}
//设置window对象的name属性
window.name = "wlop";
const WLOP = {
name: "鬼刀"
}
//直接调用
getName(); //wlop
getName1();//wlop
//call 方法调用
getName.call(WLOP);//鬼刀
getName1.call(WLOP);//wlop
// 2. 不能作为构造实例化对象
// let Person=(name,age)=>{
// this.name = name
// this.age = age
// }
// let me = new Person("wlop",16)
// console.log(me); //报错--Person is not a constructor
// 3. 不能使用arguments变量
// let fun=()=>{
// console.log(arguments);
// }
// fun(1,2,3);//报错--arguments is not defined
// 4. 箭头函数的简写
// 1). 省略小括号:当形参有且只有一个的时候
let add = n => {
return n+n
}
console.log(add(2)); //4
// 2). 省略花括号:当代码体只有一条语句的时候,此时return也要省略,而且语句的执行结果就是函数的返回值
let pow = n => n * n
console.log(pow(9)); //81
// ES6 允许给函数参数赋值初始值
// 1. 形参的初始值:具有默认值的参数,一般放在最后面(潜规则)
function add(a, b, c = 10) {
return a + b + c
}
let result = add(1, 2)
let result1 = add(1, 2, 3)
console.log(result); //13
console.log(result1); //6
// 2. 与解构赋值相结合使用
1):
function connect({ host, userName ,password,port}) {
console.log(host); // localhost
console.log(userName,password,port)
}
connect({
host: "localhost",
userName: "root",
password: "root",
port: "3306"
})
2):
function connect1({ host="baidu.com", userName,password,port }) {
console.log(host); //baidu.com
console.log(userName,password,port)
}
connect1({
userName: "root",
password: "root",
port: "3306"
})
// ES6 引入rest参数 用于获取函数的实参,用于代替arguments
// ES5获取实参的方式
function date(){
console.log(arguments);
}
date("黑圣堂","白圣堂","血天使")
//Arguments(3) ['黑圣堂', '白圣堂', '血天使', callee: ƒ, Symbol(Symbol.iterator): ƒ]
// ES6获取rest参数
function character(...args){
console.log(args);
}
character("黑圣堂","白圣堂","血天使") // ['黑圣堂', '白圣堂', '血天使']
// 注意:rest参数必须要存放在参数的最后
function fn(a,b,...args){
console.log(a); //1
console.log(b); //2
console.log(args); // [3, 4, 5, 6, 7, 8]
}
fn(1,2,3,4,5,6,7,8)
ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。它是JavaScript语言的第七种数据类型,是一种类似于字符串的数据类型
// 1. 创建Symbol
let s = Symbol()
console.log(s, typeof s); //Symbol() 'symbol'
let s2 = Symbol("wlop")
let s3 = Symbol("wlop")
console.log(s2 == s3); //false
let s4 = Symbol.for("wlop")
console.log(s4, typeof s4); //Symbol(wlop) 'symbol'
let s5 = Symbol.for("wlop")
console.log(s4 === s5); //true
// 2. 不能与其他数据进行运算
// let result = s + 100 //报错--Cannot convert a Symbol value to a number
// let result1 = s > 100 //报错--Cannot convert a Symbol value to a number
// let result3 = s + s //报错--Cannot convert a Symbol value to a number
数据类型:USONB---you are so niubility
u:undefined
s:string symbol
o:object
n:null number
b:boolean
// 给对象添加Symbol类型的属性
// 第一种:
let game={
name:"wlop",
up(){},
down(){}
}
//声明一个对象
let methods={
up:Symbol(),
down:Symbol()
}
game[methods.up]=function(){
console.log("up方法");
}
game[methods.down]=function(){
console.log("down方法");
}
console.log(game);
// 第二种:
let youxi ={
name:"狼人杀",
[Symbol("say")](){
console.log("我可以发言");
},
[Symbol("zibao")](){
console.log("我可以自爆");
}
}
console.log(youxi);
具体属性详情:Symbol - JavaScript | MDN
// 1. Symbol.hasInstance
class Person{
static [Symbol.hasInstance](param){
console.log(param);
console.log("我被用来检测类型了");
return false
}
}
let o ={}
console.log( o instanceof Person);
// 2. Symbol.isConcatSpreadable
let arr = [1,2,3]
let list = [4,5,6]
console.log(arr.concat(list));//[1, 2, 3, 4, 5, 6]
list[Symbol.isConcatSpreadable]=false;
console.log(arr.concat(list)); //[1, 2, 3, Array(3)]
// 3. 具体其他属性可点击链接:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Symbol
迭代器(Iterator)是一种接口,为了各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator接口,就可以完成遍历操作。
1. ES6创造了一种新的遍历命令for...of循环,Iterator接口主要供for...of消费
2. 原生具备iterator接口的数据(可用for of遍历)
3. 工作原理
注意:需要自定义遍历数据的时候,要想到迭代器
//声明一个数组
const xiyouji = ["唐玄藏","孙悟空","猪八戒","沙悟净"]
// 1. 使用 for...of循环---保存的是键值
for(let i of xiyouji){
console.log(i); //唐玄藏 孙悟空 猪八戒 沙悟净
}
// 2. 使用 for...in循环---保存的是键名
for(let i in xiyouji){
console.log(i);// 0 1 2 3
}
//工作原理
let iterator = xiyouji[Symbol.iterator]()
console.log(iterator.next()); //{value: '唐玄藏', done: false}
console.log(iterator.next()); //{value: '孙悟空', done: false}
console.log(iterator.next()); //{value: '猪八戒', done: false}
console.log(iterator.next()); //{value: '沙悟净', done: false}
console.log(iterator.next()); //{value: undefined, done: true}
//应用
// 需求-1 使用for...of遍历,每次返回的结果是数组里面的每个成员
//声明一个对象
const wlop = {
name: "鬼刀",
character: [
"黑圣堂",
"白圣堂-卡塔利斯",
"血天使-奥斯丁",
"天剑-南风",
],
[Symbol.iterator](){
//索引变量
let index = 0
let self = this
return {
next(){
if(index
生成器函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同
//生成器其实就是一个特殊的函数
// 1. 生成器函数的声明与调用
function* gen() {
// console.log("Hello 风铃");
yield "风铃"
// console.log("Hello 风曳");
yield "风曳"
// console.log("Hello 海琴烟(冰公主)");
yield "海琴烟(冰公主)"
// console.log("hello 鬼刀");
}
let iterator = gen()
// iterator.next(); // Hello 风铃
// iterator.next(); // Hello 风曳
// iterator.next(); // Hello 海琴烟(冰公主)
// iterator.next(); // Hello 鬼刀
console.log(iterator.next()); //{value: '风铃', done: false}
console.log(iterator.next()); //{value: '风曳', done: false}
console.log(iterator.next()); //{value: '海琴烟(冰公主)', done: false}
console.log(iterator.next()); //{value: undefined, done: true}
//遍历
for (let i of gen()) {
console.log(i); //风铃 风曳 海琴烟(冰公主)
}
// 2. 生成器函数参数
function* generator(arg) {
console.log(arg); //黑圣堂
let one =yield "燃焰玫瑰-云娜"
console.log(one); //大祭司-艾尔萨拉
let two = yield "独狼-西凌斯"
console.log(two); //大漠泰坦-洪都
let three = yield "银白-卡因"
console.log(three); //天都
}
//执行获取迭代器对象
let iterator1 = generator("黑圣堂")
console.log(iterator1.next());
// next方法可以传入实参
console.log(iterator1.next("大祭司-艾尔萨拉")); //将作为第一个yield语句的返回结果
console.log(iterator1.next("大漠泰坦-洪都"));//将作为第二个yield语句的返回结果
console.log(iterator1.next("天都"));//将作为第三个yield语句的返回结果
// 需求 -1 1s后控制台输出111 2s后输出222 3s后输出333
function one() {
setTimeout(() => {
console.log(111);
iterator.next()
}, 1000)
}
function two() {
setTimeout(() => {
console.log(222);
iterator.next()
}, 2000)
}
function three() {
setTimeout(() => {
console.log(333);
iterator.next()
}, 3000)
}
function* gen() {
yield one()
yield two()
yield three()
}
//调用生成器函数
let iterator = gen()
iterator.next();
// 需求 -2 模拟获取:用户数据、订单数据、商品数据
function getUsers() {
setTimeout(() => {
let data = "用户数据";
//调用next方法并把数据传入
iterator1.next(data);
}, 1000)
}
function getOrders() {
setTimeout(() => {
let data = "订单数据";
iterator1.next(data);
}, 1000)
}
function getGoods() {
setTimeout(() => {
let data = "商品数据"
iterator1.next(data);
}, 1000)
}
function* generator() {
let users = yield getUsers()
console.log(users);
let orders = yield getOrders()
console.log(orders);
let goods = yield getGoods()
console.log(goods);
}
//调用生成器函数
let iterator1 = generator()
iterator1.next();
详情:Promise - JavaScript | MDN
视频学习:尚硅谷Web前端Promise教程从入门到精通_哔哩哔哩_bilibili
视频学习做的笔记
Promise是ES6引入的异步编程的新的解决方案。
语法上Promise是一个构造函数,用来封装异步操作并可以获取其成功或者失败的结果
//实例化Promise对象
const P = new Promise((reslve, reject) => {
setTimeout(() => {
//数据读取成功的
// let data = "数据库中的用户数据";
// reslve(data)
//数据读取失败的
let error = "数据读取失败";
reject(error)
}, 1000)
})
P.then(res=> {
//成功的回调
console.log(res); //数据库中的用户数据
}).catch(error => {
console.log(error); //数据读取失败
})
// 1. Promise封装AJAX请求
const P = new Promise((resolve, reject) => {
// a:创建对象
const xhr = new XMLHttpRequest()
// b:初始化
xhr.open("GET", "https://api.apiopen.top/getJoke")
// c:发送
xhr.send()
// d:绑定事件,处理响应结果
xhr.onreadystatechange = function () {
//判断
if (xhr.readyState === 4) {
//判断响应状态吗
if (xhr.status >= 200 && xhr.status < 300) {
//表示成功
resolve(xhr.response)
} else {
reject(xhr.status)
}
}
}
})
P.then(res=>{
console.log(res);
}).catch(error=>{
console.error(error);
})
ES6提供了新的数据结构Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了iterator接口,所以可以使用【扩展运算符】和【for...of】进行遍历
集合的属性和方法
//声明一个集合
let s = new Set()
console.log(s,typeof s); //Set(0) 'object'
let s1= new Set([1,2,3,4,1,2])
console.log(s1); //Set(4) {1, 2, 3, 4}
// 1. 元素的个数:size
console.log(s1.size); //4
// 2. 添加元素add
s1.add(6)
console.log(s1); //Set(5) {1, 2, 3, 4, 6}
// 3. 删除 delete
s1.delete(6)
console.log(s1); //Set(4) {1, 2, 3, 4}
// 4. 检测has
console.log(s1.has(1)); //true
console.log(s1.has(6)); //false
// 5. 清空clear
// s1.clear()
// console.log(s1); //Set(0) {size: 0}
// 遍历
for(let i of s1){
console.log(i); // 1 2 3 4
}
let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1]
// 需求 -1 数组去重
let result = [...new Set(arr)]
console.log(result); // [1, 2, 3, 4, 5]
// 需求 -2 交集
let arr1 = [4, 5, 6, 5, 6]
let result1 = [...new Set(arr)].filter(item => new Set(arr1).has(item))
console.log(result1); // [4, 5]
// 需求 -3 并集
let arr2 = [4, 5, 6, 5, 6]
let result2 = [...new Set([...arr, ...arr2])]
console.log(result2); // [1, 2, 3, 4, 5, 6]
// 需求 -4 差集
let arr3 = [4, 5, 6, 5, 6]
let result3 = [...new Set(arr)].filter(item => !(new Set(arr1).has(item)))
console.log(result3); // [1, 2, 3]
ES6提供了Map数据结构。它类似于对象,也是键值对的集合。但是"键"的范围不限于字符串,各种类型的值(包括对象)都可以当做键。Map也实现了iterator接口,所以可以使用【扩展运算符】和【for...of】进行遍历
Map的属性和方法
//声明Map
let m = new Map()
console.log(m, typeof m); //Map(0) {size: 0} 'object'
// 1. 添加元素set
m.set("name","wlop")
console.log(m); //Map(1) {'name' => 'wlop'}
m.set("change",function(){ console.log("I Loe You"); })
console.log(m); //Map(2) {'name' => 'wlop', 'change' => ƒ}
let key = {
work:"鬼刀"
}
m.set(key,["北京","杭州","深圳"])
console.log(m); //Map(3) {'name' => 'wlop', 'change' => ƒ, {…} => Array(3)}
// 2. 元素个数size
console.log(m.size); // 3
// 3. 删除元素delete
m.delete('name')
console.log(m); //Map(2) {'change' => ƒ, {…} => Array(3)}
// 4. 获取get
console.log(m.get("change")); //ƒ (){ console.log("I Loe You"); }
console.log(m.get(key)); //['北京', '杭州', '深圳']
// 5. 清空clear
// m.clear()
// console.log(m); //Map(0) {size: 0}
// 遍历
for(let i of m){
console.log(i);
// ['北京', '杭州', '深圳'] 、 ['change', ƒ] 、 [{…}, Array(3)]
}
ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。基本上,ES6的class可以看做只是一个语法糖,他的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已
知识点:
// ES5
function Phone(brand, price) {
this.brand = brand
this.price = price
}
// 添加方法
Phone.prototype.call = function () {
console.log("手机");
}
// 实例化对象
let Huawei = new Phone("华为", 5999)
Huawei.call() //手机
console.log(Huawei); //Phone {brand: '华为', price: 5999}
// ES6
class Phone1 {
//构造方法
constructor(brand, price) {
this.brand = brand
this.price = price
}
//方法必须使用该语法,不能使用ES5的完整对象形式
call(){
console.log("我可以打电话");
}
}
let OPPO = new Phone1("OPPO",4999)
OPPO.call() //我可以打电话
console.log(OPPO); //Phone1 {brand: 'OPPO', price: 4999}
class Phone{
static name="手机"
static cahnge(){
console.log("我可以改变世界");
}
}
let nokia = new Phone()
console.log(nokia.name); //undefined
console.log(Phone.name); //手机
class Wlop {
//构造方法
constructor(name, age) {
this.name = name
this.age = age
}
//父类的成员属性
call() {
console.log("鬼刀");
}
}
class Fans extends Wlop {
//构造方法
constructor(name, age, ability, arms) {
super(name, age)
this.ability = ability
this.arms = arms
}
occupation() {
console.log("职业");
}
city() {
console.log("城市");
}
call(){
console.log("子类自己的方法")
}
}
const character = new Fans("海琴烟", 18, "和动物交流", "手")
character.call()
// 子类没有call方法时打印:鬼刀 --- 子类有自己的call方法时打印:子类自己的方法
character.occupation() //职业
character.city() //城市
console.log(character);
//Fans {name: '海琴烟', age: 18, ability: '和动物交流', arms: '手'}
子类对父类方法的重写
就是就近原则:如果子类中有和父级同名的方法,则会调用自己的方法
class Wlop {
// 对对象的动态属性进行封装
get work() {
console.log("作品");
return "I Love You"
}
//set必须要有一个参数
// 添加控制、判断
set work(newVal) {
console.log("设置作品");
}
}
//实例化对象
let w = new Wlop()
console.log(w.work); // 函数里面的返回值就是属性的值
w.work = "鬼刀" // 设置后会执行打印:设置作品
具体详情:Number - JavaScript | MDN
// 1. Number.EPSILON 是 JavaScript 表示的最小精度---误差如果小于这个值,就近似于相等
// 作用:浮点数计算,对精度进行设置
console.log(0.1 + 0.2); // 0.30000000000000004
function equal(a, b) {
if (Math.abs(a - b) < Number.EPSILON) {
return true
} else {
return false
}
}
console.log(0.1 + 0.2 === 0.3); // false
console.log(equal(0.1 + 0.2, 0.3)); // true
// 2. 二进制和八进制
// 1):二进制
let b = 0b1010
console.log(b); // 10
// 2):八进制
let o = 0o777;
console.log(o); // 511
// 3):十进制
let d = 100;
console.log(d); // 100
// 4):十六进制
let x = 0xff;
console.log(x); // 255
// 3. Number.isFinite 检测一个数值是否为有限数
console.log(Number.isFinite(100)); // true
console.log(Number.isFinite(Infinity)); // false
// 4. Number.isNaN 检测一个数值是否为NaN
console.log(Number.isNaN(123)); // false
console.log(Number.isNaN(NaN)); // true
// 5. Number.parseInt Number.parseFloat 字符串转整数(数字)
console.log(Number.parseInt("521我爱你")); // 521
console.log(Number.parseFloat("3.1415926派")); // 3.1415926
// 6. Number.isInteger 判断一个数是否为整数
console.log(Number.isInteger(5)); // true
console.log(Number.isInteger(5.2)); // false
// 7. Math.trunc 将数字的小数部分抹去
console.log(Math.trunc(5.2)); // 5
// 8. Math.sign 判断一个数到底为正数、负数、还是零
console.log(Math.sign(-6)); // -1
console.log(Math.sign(6)); // 1
console.log(Math.sign(0)); // 0
具体详情:Object - JavaScript | MDN
// 1. Object.is 判断两个值是否完全相等
console.log(Object.is(120, 121)); //false
console.log(Object.is(120, "120")); //false
console.log(Object.is(NaN, NaN)); //true
console.log(NaN === NaN); //false
// 2. Object.assign 对象的合并
const config1 = {
host: "localhost",
port: "3306",
name: "root",
password: "root"
}
const config2 = {
host: "www.baidu.com",
port: "8080",
name: "百度",
// password: "root"
}
console.log(Object.assign(config1, config2));
// {host: 'www.baidu.com', port: '8080', name: '百度', password: 'root'}
// 3. Object.setPrototypeOf--设置原型对象 Object.getPrototypeOf--湖获取原型
const wlop = {
name: "鬼刀"
}
const character = {
charact: ["天僧-皓月", "凯烈", "贝依"]
}
Object.setPrototypeOf(wlop, character)
console.log(wlop);
console.log(Object.getPrototypeOf(wlop)); //{charact: Array(3)}
模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来
模块功能主要有两个命令构成:export 和 import
m.js
//分别暴露
export let author = "wlop";
export function work() {
console.log("鬼刀");
}
m1.js
// 统一暴露
let author1 = "wlop";
function work1() {
console.log("鬼刀");
}
export { author1, work1 }; // 对象简写
m2.js
//默认暴露
// 暴露可以是任意类型:数字、对象、函数...(对象居多)
export default{
author2:"wlop",
work2(){
console.log("鬼刀");
}
}
运行时报错(CORS 跨域报错)
Access to script at 'file:///E:/sunli/desktop/proctice/m1.js'
from origin 'null' has been blocked by CORS policy: Cross origin
requests are only supported for protocol schemes:
http, data, chrome, chrome-extension, chrome-untrusted, https.
解决方法:
1. Vscode下载插件:Live Server
2. 右键html文件:Open with Live Server
浏览器使用ES6模块化语法二
新建一个入口文件app.js,把import 的引入全部放在app.js中,在htm文件中直接src引入
babel官网:Babel 中文网 · Babel - 下一代 JavaScript 语法的编译器
* 需要安装工具
- babel-cli:babel命令行工具
- babel-preset-env:预设包-能够转换成es5语法
- browserify:打包工具(webpack)
* 1. 先初始化:npm i
* 2. 安装工具:npm i babel - cli babel - preset - env browserify - D
* 3. npx babel js -d dist/js --presets=babel-preset-env
* 4. 打包:npx browserify dist/js/app.js -o dist/bundle.js
* 5. 在页面中引入:
includes方法用来检测数组中是否包含某个元素,返回布尔类型值
let mingzhu = ["西游记","红楼梦","三国演义","水浒传"]
console.log(mingzhu.includes("西游记")); // true
console.log(mingzhu.includes("金瓶梅")); // false
在ES7中引入指数运算符【**】,用来实现幂运算,功能与Math.pow结果相同
console.log(2**10); //1024
console.log(Math.pow(2,10)); //1024
async和await两种语法结合可以让异步代码像同步代码一样
// async 函数
async function func() {
// 1. 返回一个非promise对象
// return "wlop"
//只要返回的结果不是一个promise类型的对象,则这个函数的返回结果就是成功的promise
// 2. 抛出错误
// throw new Error("出错了")
// 3. 返回的结果就是一个promise对象
return new Promise((resolve, reject) => {
// resolve("成功了")
reject("失败了")
})
}
const result = func()
console.log(result); //Promise {: 'wlop'}
result.then(res => {
console.log(res);
}).catch(error => {
console.log(error);
})
// await 要放在async函数中,但是async里面可以没有await
const P = new Promise((resolve, reject) => {
// resolve("success")
// resolve("用户数据")
reject("失败了")
})
async function main() {
try {
let result = await P
// console.log(result); // success
// console.log(result); // 用户数据
} catch (error) {
console.log(error); //失败了
}
}
main()
// 1. Object.values和Object.entries
// Object.values()方法返回一个给定对象的所有可枚举属性值的数组
// Object.entries()方法返回一个给定对象自身可遍历属性【key,value】的数组
const wlop = {
name: "鬼刀",
character: ["黑圣堂", "白圣堂", "血天使", "南风"],
arms: ['修罗', '鬼刀', '叹息', '流光(已毁)', '审判', '彷徨', '魔灵', '狂砂', '血刺(已毁)', '新月']
}
// 获取对象所有的键
console.log(Object.keys(wlop)); // ['name', 'character', 'arms']
// 获取对象所有的值
console.log(Object.values(wlop)); // ['鬼刀', Array(4), Array(10)]
// entries
console.log(Object.entries(wlop)); // [Array(2), Array(2), Array(2)]
// 创建Map
const m = new Map(Object.entries(wlop))
console.log(m); // Map(3) {'name' => '鬼刀', 'character' => Array(4), 'arms' => Array(10)}
console.log(m.get("name")); // 鬼刀
console.log(m.get("character")); // ['黑圣堂', '白圣堂', '血天使', '南风']
// 2. Object.getOwnPropertyDescriptors 该方法返回指定对象所有自身属性的描述对象【可以进行对象深层次的克隆】
console.log(Object.getOwnPropertyDescriptors(wlop)); //{name: {…}, character: {…}, arms: {…}}
const obj = Object.create(null, {
name: {
//设置值
value: "海琴烟",
//属性特征
writable: true, // 是否可写
configurable: true, // 是否可以删除
enumerable: true, // 是否可以枚举
}
})
// rest参数与spread扩展运算符在ES6中已经引入,但只是针对数组
// 在ES9中为对象提供了向数组一样的rest参数和扩展运算符
// 1. rest参数
function connect({host,post,...user}){
console.log(host,post,user);
// 127.0.0.1 3306 {username: 'root', password: 'root', type: 'master'}
}
const obj = {
host:"127.0.0.1",
post:3306,
username:"root",
password:"root",
type:"master"
}
connect(obj)
// 2. 扩展运算符
const wlop1 = {arms1:"鬼刀"}
const wlop2 = {arms2:"修罗"}
const wlop3 = {arms2:"叹息"}
const wlop4 = {arms3:"审判"}
const arms = {...wlop1,...wlop2,...wlop3,...wlop4}
console.log(arms); //{arms1: '鬼刀', arms2: '叹息', arms3: '审判'}
//需求 -1 提取url与【标签文本】
//声明一个字符串
let str = '百度'
//一: 之前的方法
const reg1 = /(.*)<\/a>/
// // 执行
const result1 = reg1.exec(str)
console.log(result1);
// //['百度', 'https:www.baidu.com', '百度', index: 0, input: '百度', groups: undefined]
// // 1. 第零个元素;是整个正则匹配的结果。
// // 2. 第一个元素:是第一个小括号匹配到的结果,
// // 3. 第二个元素:是第二个小括号匹配到的结果
console.log(result1[1]); //https:www.baidu.com
console.log(result1[2]); //百度
// 二:命名捕获分组方法
const reg = /(?.*)<\/a>/
const result = reg.exec(str)
console.log(result);
//['百度', 'https:www.baidu.com', '百度', index: 0, input: '百度', groups: {…}]
console.log(result.groups.url); //https:www.baidu.com
console.log(result.groups.text); //百度
let str = 'GSJJ1654的就是不对接口215佛挡杀'
// 一、正向断言
const reg = /\d+(?=佛)/
const result = reg.exec(str)
console.log(result);
//['215', index: 15, input: 'GSJJ1654的就是不对接口215佛挡杀', groups: undefined]
// 二、反向断言
const reg1 = /(?<=口)\d+/
const result1 = reg1.exec(str)
console.log(result1);
// ['215', index: 15, input: 'GSJJ1654的就是不对接口215佛挡杀', groups: undefined]
let str = `
`
// 需求:把电影名称和上映日期提取出来放到一个对象里面
const reg = /.*?(.*?)<\/a>.*?(.*?)<\/p>/s
const result = reg.exec(str)
console.log(result);
const reg2 = /
.*?(.*?)<\/a>.*?(.*?)<\/p>/gs
let result2
let data = []
while (result2 = reg2.exec(str)) {
console.log(result2);
data.push({ title: result2[1], time: result2[2] })
}
console.log(data);
// Object.fromEntries:创建一个对象,接收参数是一个二维数组或者一个Map
// 二维数组
const result = Object.fromEntries([
['name', "海琴烟"],
['arms', '修罗, 鬼刀, 叹息, 流光(已毁), 审判, 彷徨, 魔灵, 狂砂, 血刺(已毁), 新月']
])
console.log(result);
//{name: '海琴烟', arms: '修罗, 鬼刀, 叹息, 流光(已毁), 审判, 彷徨, 魔灵, 狂砂, 血刺(已毁), 新月'}
//Map
const m = new Map();
m.set("name","鬼刀")
const result1 = Object.fromEntries(m)
console.log(result1); //{name: '鬼刀'}
let str = " I Love You "
console.log(str);
console.log(str.trimStart());
console.log(str.trimEnd());
// flat:将多维数组转为低维数组
const arr= [1,2,3,[4,5,6]]
console.log(arr.flat()); //[1, 2, 3, 4, 5, 6]
const arr1= [1,2,[3,4,[5,6,7]]]
console.log(arr1.flat()); //[1, 2, 3, 4, Array(3)]
console.log(arr1.flat(2)); //[1, 2, 3, 4, 5, 6, 7]
const arr2 =[1,2,3]
console.log(arr2.flatMap(item=>[item*10])); // [10, 20, 30]
//多维数组转一维数组
const list = [1,2,3,[4,5,6,[7,8,9,[10,11,12,[13,14,15]]]]]
console.log(list.flat(Infinity));
//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
let wlop = Symbol("鬼刀")
console.log(wlop.description); //鬼刀
class Person {
// 公有属性
name;
//私有属性
#age;
#weight;
//构造方法
constructor(name, age, weight) {
this.name = name
this.#age = age
this.#weight = weight
}
intro() {
console.log(girl.name); //芙不乖
console.log(girl.#age); // 18
console.log(girl.#weight); // 45kg
}
}
//实例化对象
const girl = new Person("芙不乖", 18, '45kg')
// console.log(girl.name); //芙不乖
// console.log(girl.#age); // 语法报错 --undefined
// console.log(girl.#weight); // 语法报错--undefined
girl.intro()
返回的结果状态始终是成功的,成功的值是每个promise执行的结果值和状态
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("商品数据 -1")
}, 1000)
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("商品数据 -2")
// reject("出错了")
}, 1000)
})
const result = Promise.allSettled([p1,p2])
console.log(result);
//返回的结果状态始终是成功的,成功的值是每个promise执行的结果值和状态
// Strinprototype.matchAll:得到正则批量匹配的结果
let str = `
`
const reg = /.*?(.*?)<\/a>.*?(.*?)<\/p>/gs
const result = str.matchAll(reg)
console.log(result);
// for(let i of result){
// console.log(i);
// }
const arr = [...result]
console.log(arr);
function main(config){
const dbHost = config?.db?.host
console.log(dbHost); //127.0.0.1
}
main({
db:{
host:"127.0.0.1",
port:3306
},
cache:{
host:"192.168.10.111",
port:8080
}
})
import('./app.js').then(()=>{
console.log('动态引入');
});
详情:BigInt - JavaScript | MDN
详情:globalThis - JavaScript | MDN
console.log(globalThis);
视频:
尚硅谷Web前端ES6教程,涵盖ES6-ES11_哔哩哔哩_bilibili
文档:1. ES6 入门教程
正则MDN文档:RegExp(正则表达式) - JavaScript | MDN