目录
4. Symbol.prototype.description
3. Strinprototype.matchAll()--得到正则批量匹配的结果
前言
课程介绍
- ES介绍(ES全称EcmsScript,是脚本语言的规范,而平时经常编写的jsvascript,是EcmaScript的一种实现,所以ES新特性其实指的就是javascript新特性)
- 为什么要学习ES新特性(1.语法简洁,功能丰富 2.框架开发应用 3.前端开发职位要求)
- 前置知识(1.JavaScript基础语法 2.JAX和NodeJS)
- 前置知识(1.由浅入深,通俗易懂 2.案例穿插)
一、ECMASript相关介绍
1.什么是ECMA
ECMA(European Computer Manufacturers Association)中文名称为欧洲计算机制造商协会。这个组织的目标是评估、开发和认可电信和计算机标准。1944年后该组织改名为Ecma国际
2. 什么是ECMAScript
ECMAScript是由Ecma国际通过ECMA-262标准化的脚本程序设计语言。
3. 什么是ECMA-262
Ecma国际制定了许多标准,而ECMA-262只是其中的一种,所有的标准列表查看
4. ES6兼容性
ECMAScript 6 compatibility table可查看兼容性
二、ES6-变量声明
1.let
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. 案例
<style>
.item{
width: 100px;
height: 100px;
margin-left: 20px;
border: 1px solid green;
display:inline-block
}
</style>
<div class="container">
<h2 id="h2">点击切换颜色</h2>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<script>
let items = document.getElementsByClassName('item')
for(let i=0 ; i<items.length ; i++){
items[i].onclick = function(){
items[i].style.background = "skyblue"
}
}
</script>
2.const(定义常量)
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("唐玄奘")
3. 变量的解构赋值
// 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() //可以和动物交流
4. 模板字符串
// ES6 引入新的声明字符串的方式:反引号:``
// 1. 声明
let str =`我也是字符串`
console.log(typeof str,str);//string 我也是字符串
// 特性
// 1. 内容中可以直接出现换行符
let str1 = `<ul>
<li>郭德纲</li>
<li>岳云鹏</li>
<li>郭麒麟</li>
</ul>`
// 2. 变量拼接
let lovest = "郭麒麟";
let out = `${lovest}是三个人中最年轻的`
console.log(out); //郭麒麟是三个人中最年轻的
5. 对象的简化写法
// 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: ƒ}
6. 箭头函数以及声明特点
// 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
7. 箭头函数的实践与应用场景
<style>
div {
width: 200px;
height: 200px;
background: skyblue;
}
</style>
<body>
<div id="ad"></div>
<script>
// 需求-1 点击div 2s后颜色变成红色
// 1. 获取元素
let ad = document.getElementById("ad")
// 2. 绑定事件
ad.addEventListener("click", function () {
//定时器
setTimeout(() => {
this.style.background = "red"
}, 2000)
})
// 需求-2 从数组中返回偶数的元素
const ARR = ["1", "2", "6", "8", "11", "13"]
// const RESULT = ARR.filter(item => {
// if (item % 2 === 0) {
// return true
// } else {
// return false
// }
// })
const RESULT = ARR.filter(item => item % 2 === 0)
console.log(RESULT);
//
// 1.适合场景 与this无关的回调:定时器、数组方法的回调
// 2.不合适场景:与this有关的回调:事件回调、对象的方法
</script>
</body>
8. 函数参数的默认值设置
// 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"
})
9. rest参数
// 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)
10.扩展运算符
<body>
<div></div>
<div></div>
<div></div>
<script>
// 【...】扩展运算符能将【数组】转换为逗号分割的【参数序列】
// 1. 介绍
//声明一个数组
const TFBOYS = ["王俊凯", "王源", "易烊千玺"]
//声明一个函数
function chunwan() {
console.log(arguments);
}
chunwan(...TFBOYS)
// 2. 应用
// 1):数组的合并
const ANIMATION = ["海绵宝宝","章鱼哥","派大星"]
const MUSIC = ["凤凰传奇","Twins","五月天"]
const combination=[...ANIMATION,...MUSIC]
console.log(combination);
//['海绵宝宝', '章鱼哥', '派大星', '凤凰传奇', 'Twins', '五月天']
// 2):数组的克隆
const LETTER = ["A","B","D"]
const clone = [...LETTER]
console.log(clone);//["A","B","D"]
// 3):将伪数组转为真正的数组
const divs = document.querySelectorAll("div")
const divArr = [...divs]
console.log(divArr);//[div, div, div]
</script>
</body>
11.Symbol
11.1 Symbol的介绍与创建
ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。它是JavaScript语言的第七种数据类型,是一种类似于字符串的数据类型
- Symbol的只是唯一的,用来解决命名冲突的问题
- Symbol值不能与其他数据进行运算
- Symbol定义的对象属性不能使用for...in循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名
// 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
11.2 .对象添加Symbol类型的属性
// 给对象添加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);
11.3 Symbol内置属性
具体属性详情: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
12.迭代器的介绍
迭代器(Iterator)是一种接口,为了各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator接口,就可以完成遍历操作。
1. ES6创造了一种新的遍历命令for...of循环,Iterator接口主要供for...of消费
2. 原生具备iterator接口的数据(可用for of遍历)
- Array
- Arguments
- Set
- Map
- String
- TypedArray
- NodeList
3. 工作原理
- 创建一个指针对象,指向当前数据结构的起始位置
- 第一次调用对象的next方法,指针自动指向数据结构的第一个成员
- 接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员
- 每调用next方法返回一个包含value和done属性的对象
注意:需要自定义遍历数据的时候,要想到迭代器
//声明一个数组
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<self.character.length){
const result = {value:self.character[index],done:false}
//下标自增
index++
//返回结果
return result
}else{
return {value:undefined,done:true}
}
}
};
}
}
//遍历这个对象
for(let i of wlop){
console.log(i); // 黑圣堂 白圣堂-卡塔利斯 血天使-奥斯丁 天剑-南风
}
13. 生成器
生成器函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同
13.1 生成器函数的声明与调用
//生成器其实就是一个特殊的函数
// 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); //风铃 风曳 海琴烟(冰公主)
}
13.2 生成器函数参数
// 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语句的返回结果
13.3 生成器函数实例
// 需求 -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();
14. Promise
视频学习:尚硅谷Web前端Promise教程从入门到精通_哔哩哔哩_bilibili
视频学习做的笔记
Promise是ES6引入的异步编程的新的解决方案。
语法上Promise是一个构造函数,用来封装异步操作并可以获取其成功或者失败的结果
- Promise构造函数:Promise(excutor){}
- Promise.prototype.then()方法
- Promise.prototype.catch()方法
14.1 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);
})
15. Set
ES6提供了新的数据结构Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了iterator接口,所以可以使用【扩展运算符】和【for...of】进行遍历
集合的属性和方法
- size:返回集合的元素个数
- add:增加一个新元素,返回当前合集
- delete:删除元素,返回boolean值
- has:检测集合中是否包含某个元素,返回boolean值
- clear:清空合集,返回undefined
//声明一个集合
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]
16. Map
ES6提供了Map数据结构。它类似于对象,也是键值对的集合。但是"键"的范围不限于字符串,各种类型的值(包括对象)都可以当做键。Map也实现了iterator接口,所以可以使用【扩展运算符】和【for...of】进行遍历
Map的属性和方法
- size:返回Ma的元素个数
- set:增加一个新元素,返回当前Map
- get:返回键名对象的键值
- has:检测Map中是否包含某个元素,返回boolean值
- clear:清空合集,返回undefined
//声明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)]
}
17. Class类
ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。基本上,ES6的class可以看做只是一个语法糖,他的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已
知识点:
- class声明类
- constructor定义构造函数初始化
- extends继承父类
- super调用父级构造方法
- static定义静态方法和属性
- 父类方法可以重写
17.1 初体验
// 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}
17.2 class静态成员static
class Phone{
static name="手机"
static cahnge(){
console.log("我可以改变世界");
}
}
let nokia = new Phone()
console.log(nokia.name); //undefined
console.log(Phone.name); //手机
17.3 构造函数继承
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: '手'}
子类对父类方法的重写
就是就近原则:如果子类中有和父级同名的方法,则会调用自己的方法
17.4 class中getter和setter设置
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 = "鬼刀" // 设置后会执行打印:设置作品
18. ES6数值扩展
具体详情: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
19. 对象方法扩展
具体详情: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)}
20. 模块化
模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来
20.1 模块化开发的好处
- 防止命名冲突
- 代码复用
- 高维护性
20.2 ES6模块化语法
模块功能主要有两个命令构成:export 和 import
- export 命令用于规范模块的对外接口
- import 命令用于输入其他模块提供的功能
<script type="module">
1. 通用的导入方式
import * as m from "./m.js"
console.log(m);
console.log(m.author); //wlop
import * as m1 from "./m1.js"
console.log(m1);
m1.work1(); //鬼刀
import * as m2 from "./m2.js"
console.log(m2);
m2.default.work2() //鬼刀
2. 解构赋值形式
import {author,work} from "./m.js"
console.log(author); // wlop
console.log(work); //ƒ work() { console.log("鬼刀");}
import {author as name,work1} from "./m1.js" //重名的话可以使用 as 重命名
console.log(name); // wlop
console.log(work1); //ƒ work() { console.log("鬼刀");}
import {default as def} from "./m2.js" //不能直接使用default,需要重命名
console.log(def); // {author2: 'wlop', work2: ƒ}
3. 简便形式(只能针对默认暴露)
import defa from './m2.js'
console.log(defa); // {author2: 'wlop', work2: ƒ}
import part from './m.js'
console.log(part);
//报错--Uncaught SyntaxError:
//The requested module './m.js' does not provide an export named 'default'
</script>
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引入
<script src="./app.js" type="module"></script>
21. babel对ES6模块化代码转换
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. 在页面中引入:<script src="dist/bundle.js"></script>
22. ES6模块化引入NPM包
- 安装所需要的依赖包:npm i 包
- 在需要的页面引入:import 名称 from "包"
三、ES7新特性
1. Array.prototype.includes
includes方法用来检测数组中是否包含某个元素,返回布尔类型值
let mingzhu = ["西游记","红楼梦","三国演义","水浒传"]
console.log(mingzhu.includes("西游记")); // true
console.log(mingzhu.includes("金瓶梅")); // false
2. 指数操作符
在ES7中引入指数运算符【**】,用来实现幂运算,功能与Math.pow结果相同
console.log(2**10); //1024
console.log(Math.pow(2,10)); //1024
四、ES8新特性
1. async和await
async和await两种语法结合可以让异步代码像同步代码一样
1.1 async
- async函数的返回值为promise对象
- promise对象的结果由async函数执行的返回值决定
// 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 {<fulfilled>: 'wlop'}
result.then(res => {
console.log(res);
}).catch(error => {
console.log(error);
})
1.2 await表达式
- await必须写在async函数中
- await右侧的表达是一般为promise对象
- await返回的promise成功的值
- await的promise失败了,就会抛出异常,需要通过try...catch捕获处理
// 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()
2. ES8对象方法扩展
- Object.values();
- Object.entries();
- Object.getOwnPropertyDescriptors();
// 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, // 是否可以枚举
}
})
五、ES9
1. 扩展运算符和rest参数
// 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: '审判'}
2. 正则扩展--命名捕获分组
//需求 -1 提取url与【标签文本】
//声明一个字符串
let str = '<a href="https:www.baidu.com">百度</a>'
//一: 之前的方法
const reg1 = /<a href="(.*)">(.*)<\/a>/
// // 执行
const result1 = reg1.exec(str)
console.log(result1);
// //['<a href="https:www.baidu.com">百度</a>', 'https:www.baidu.com', '百度', index: 0, input: '<a href="https:www.baidu.com">百度</a>', groups: undefined]
// // 1. 第零个元素;是整个正则匹配的结果。
// // 2. 第一个元素:是第一个小括号匹配到的结果,
// // 3. 第二个元素:是第二个小括号匹配到的结果
console.log(result1[1]); //https:www.baidu.com
console.log(result1[2]); //百度
// 二:命名捕获分组方法
const reg = /<a href="(?<url>.*)">(?<text>.*)<\/a>/
const result = reg.exec(str)
console.log(result);
//['<a href="https:www.baidu.com">百度</a>', 'https:www.baidu.com', '百度', index: 0, input: '<a href="https:www.baidu.com">百度</a>', groups: {…}]
console.log(result.groups.url); //https:www.baidu.com
console.log(result.groups.text); //百度
3. 正则扩展--反向断言
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]
4. 正则扩展--dotAll模式
let str = `
<ul>
<li>
<a> 肖申克的救赎</a>
<p>上映时间:1994-09-10</p>
</li>
<li>
<a>阿甘正传</a>
<p>上映时间:1994-07-06</p>
</li>
</ul>
`
// 需求:把电影名称和上映日期提取出来放到一个对象里面
const reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/s
const result = reg.exec(str)
console.log(result);
const reg2 = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/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);
六、ES10
1. Object.fromEntries()
// 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: '鬼刀'}
2. 字符串扩展方法
- trimStart()----清除字符串左侧空格
- trimEnd()---清除字符串右侧空格
let str = " I Love You "
console.log(str);
console.log(str.trimStart());
console.log(str.trimEnd());
3. 数组方法扩展
- flat
- flatMap
// 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]
4. Symbol.prototype.description
let wlop = Symbol("鬼刀")
console.log(wlop.description); //鬼刀
七、ES11
1. 私有属性
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()
2. Promise.allSettled
返回的结果状态始终是成功的,成功的值是每个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执行的结果值和状态
3. Strinprototype.matchAll()--得到正则批量匹配的结果
// Strinprototype.matchAll:得到正则批量匹配的结果
let str = `
<ul>
<li>
<a>肖申克的救赎</a>
<p>上映时间:1994-09-10</p>
</li>
<li>
<a>阿甘正传</a>
<p>上映时间:1994-07-06</p>
</li>
</ul>
`
const reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/gs
const result = str.matchAll(reg)
console.log(result);
// for(let i of result){
// console.log(i);
// }
const arr = [...result]
console.log(arr);
4. 可选链操作符 (?.)
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
}
})
5. 动态import
import('./app.js').then(()=>{
console.log('动态引入');
});
6. BIgInt类型
7. globalThis--始终指向全局对象
详情:globalThis - JavaScript | MDN
console.log(globalThis);
八、参考资料
视频:
尚硅谷Web前端ES6教程,涵盖ES6-ES11_哔哩哔哩_bilibili
文档:1. ES6 入门教程
正则MDN文档:RegExp(正则表达式) - JavaScript | MDN