let
变量声明
let a;
let a,b,c;
let e = 1;
let f =5,g = "字符串",h = [];
特性:
- 变量不能重复声明
- 块级作用域 全局 函数 eval
- 不存在变量提升
- 不影响作用域链
const
声明常量
- 一定要赋初始值
- 一般常量使用大写
- 常量的值不能修改
- 块级作用域 5.对于数组和对象的元素修改,不算对常量的修改,不会报错(地址没有改变)
解构赋值
es6允许按照一定模式从数组和对象中提取值,对变量进行赋值 1.数组的解构
const a = ['一','二','三','四'];
let [1,2,3,4] = a;
console.log(1);//一
console.log(2);//二
console.log(3);//三
console.log(4);//四
2.对象的解构
const zhao = {
name:'赵本山',
age:'不详',
xiaopin:function(){
console.log("演小品");
}
};
let {name, age, xiaopin} = zhao;
xiaopin();//直接调用不用写:zhao.xiaopin();
模板字符串
1.内容中可以直接出现换行符
2.变量拼接
let a = '小米';
let b = `${a}是一个手机`;
简化对象写法
es6允许在大括号里面,直接写入变量和函数,作为对象的属性和方法
let name = '小王';
let ch = function(){
console.log('回来了');
}
const jia = {
name,//= name: name,
ch,
jianxie(){
console.log('回来了');
}
}
箭头函数
let fn = function(){
}
let fn = () => {
}
- this 是静态的,this 始终指向函数声明时所在作用域下的this的值
- 不能作为构造函数实例化对象
3.不能使用 arguments(保存实参)变量
4.箭头函数的简写
4.1省略小括号,当形参有且只有一个时
let add = n => {
return n*n;
}
4.2 省略花括号,当代码只有一条语句时,此时return必须省略,而且语句的执行结果就是函数的返回值
let add = (n) => n*n;
箭头函数适合与this无关的回调。定时器,数组的方法回调
箭头函数不适合与this有关的回调,事件回调,对象的方法
rest参数
用于获取函数的实参,用来代替 arguments
function date(...args){
console.log(args)
}
date(1,2,3)
有其他参数时rest要放在最后
扩展运算符
"..."扩展运算符能将数组转换为逗号分隔的参数序列
const arr = [1,2,3]
function arrs(){
console.log(arguments);
}
arrs(arr);//这里是一个数组
arrs(...arr);//这里是三个参数序列
Symbol
es6引入的新的原始数据类型,表示独一无二的值,是一种类似于字符串的数据类型
1.Symbol的值是唯一的,用来解决命名冲突的问题
2.Symbol值不能与其他数据进行运算
3.Symbol定义的对象属性不能使用for...in循环遍历,但是可以用Reflect.ownKeys来获取对象的所有键名
let s = Symbol();
let s1 = Symbol('张三');
let s2 = Symbol('张三');
console.log(s1===s2)//flase
let s3 = Symbol.for('张三');
let s4 = Symbol.for('张三');
console.log(s3===s4)//true
迭代器
迭代器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。 任何数据结构只要部署Iterator接口,就可以完成遍历操作。
1.es6创造了一种新的便利命令for...of循环,Iterator接口主要提供for...of使用
2.原生具备Iterator接口的数据(可用for of遍历) a.Array b.Arguments c.Set d.Map e.String f.TypedArray g.NodeList
const arr = [1,2,3,4]
for(let v of arr){
}
生成器函数
是es6提供的一种异步编程解决方案
function * gen(){
console.log("hello generator")
yield 111;
}
let iterator = gen();
console.log(iterator)//不能打印出,要使用next()
iterator.next();
Promise
是es6引入的异步编程的新的解决方案,语法上Promise是一个构造函数, 用来封装异步操作并可以获取其成功或失败的结果
Promise 构造函数:Promise(excutor){
}
Promise.prototype.then 方法
Promise.prototype.catch 方法
Set
es6提供了新的数据结构Set(集合)。类似于数组,但成员值都是唯一的。 集合实现了iterator接口,可以使用“扩展运算符”和“for...of...”进行遍历
集合的属性和方法:
size:返回集合的元素个数
add:增加一个新元素,返回当前集合
delete:删除元素,返回boolean值
has:检测集合中是否包含某个元素,返回boolean值
clear:清空集合
声明一个set
let s = new Set();
let s1 = new Set([1,2,3,4,1])//输出1,2,3,4 去重
Map
es6提供了Map数据结构。类似于对象,也是键值对的集合,但“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map也实现了iterator接口,可用“扩展运算符”和“for...of...”进行遍历
Map的属性和方法:
size:返回集合的元素个数
set:增加一个新元素,返回当前Map
get:返回键名对象的键值
has:检Map中是否包含某个元素,返回boolean值
clear:清空集合
声明Map
let m = new Map();
添加元素
m.set('name','小翁')
m.set('hansu',function(){
console.log("这是函数")
});
class类
通过class关键字,可用定义类,es6的class可用看作一个语法糖,他的绝大部分功能,es5都能做到。class只是让对象原型的写法更加清晰,更加面向对象编程
1.constructor 定义构造函数初始化,是类的默认方法,创建类的实例化对象时被调用。
2.static 定义静态属性和方法
3.extends 继承父类
4.super 调用父级构造方法
5.父类方法可用重写
6.get和set
数值扩展
1.Number.EPSILON是js表示的最小精度(主要用于解决小数误差)
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.二进制和八进制
let b = 0b1010;//二进制
let o = 0o777;//八进制
let x = 0xff//十六进制
3.Number.isFinite(数值) 检测一个数值是否为有限数
4.Number.isNaN(数值) 检测一个数值是否为NaN
5.Number.parseInt(数值) Number.parseFlost(数值)字符串转整数
console.log(Number.parseInt('1546lj'))//1546
console.log(Number.parseInt('1546.12'))//1546
6.Number.isInteger(数值)判断一个数是否为整数,是返回true,不是返回false
7.Math.trunc(数值) 将数字的小数部分去掉
8.Math.sign(数值) 判断一个数是什么数:正数(返回1)、负数(返回1)、0(返回0)
对象方法扩展
1.Object.is(值1,值2) 判断两个值是否完全相等
console.log(Object.is(NaN,NaN))//true
console.log(NaN === NaN)//false
2.Object.assign(对象1,对象2) 对象的合并
const a = {
name:'liu'
}
const a = {
name:'zhang',
age: 10
}
console.log(Object.assign(a,b))//相同属性和方法会被后面的覆盖,不同则合并
3.Object.setPrototypeOf 设置原型对象 Object.getPrototypeOf 获取原型对象
模块化
是指将一个大的程序文件,拆分成多个小文件,然后将小文件组合起来
好处:
1.防止命名冲突
2.代码复用
3.高维护性
引入m1.js模块内容
在m1.js中要加上export暴露出来
<script type="module">
通用导入方式
import * as m1 from "./src/js/m1.js";
结构赋值形式
import {name, lanQiu} from "./src/js/m1.js";
import {name, xinWei} from "./src/js/m1.js";会显示name已经用过不能再用,可用通过下面方式
import {name as xingming, xinWei} from "./src/js/m1.js";
import {default as m3} from "./src/js/m3.js";
简便形式 只针对默认暴露
import m3 from "./src/js/m3.js";
</script>
因为全部导入都在html界面,会导致代码量过多,我们可用创建一个专门导入的入口
如:创建一个app.js,然后所有其他的导入都在app.js中完成,我们就只需要在html
中导入app.js
<script src="./src/js/app.js" type="module"></script>
分别暴露 m1.js
export let name = '小王';
export function lanQiu(){
console.log("会打篮球");
}
统一暴露 m2.js
let name = '小王';
function xinWei(){
console.log("会打篮球");
}
export {name, xinWei};
默认暴露 m3.js
export default {
name: '小王';
xinWei: function(){
console.log("会打篮球");
}
}
使用时需要在".default"后面在"."方法和属性
ES7 新特性
- Array.prototype.includes 判断数组中是否包含某元素,返回布尔类型,语法:arr.includes(元素值);
- 指数操作符 幂运算的简化写法,功能与Math.pow结果相同,例如:2的10次方:2**10,Math.pow(2,10);
ES8 新特性
async和await
async 和 await 两种语法结合可以让异步代码看起来像同步代码一样;
简化异步函数的写法;
async函数
- async 函数的返回值为 promise 对象;
- promise 对象的结果由 async 函数执行的返回值决定;
async function fn(){
只要return返回的结果不是一个promise对象,返回结果就是成功的promise对象
return '小';
如果return返回的结果是一个promise对象,如果promise对象内是成功的,那fn()
返回的结果也是成功的,promise对象成功的值就是fn()的值,失败同理。
return new Promise(resolve, reject)=>{
resolve('成功的数据')
}
}
const result = fn();
console.log(result);返回的是一个promise对象,'小'在promise 对象中
await 表达式:
- await 必须写在 async 函数中;
- await 右侧的表达式一般为 promise 对象;
- await 返回的是 promise 成功的值;
- await 的 promise 失败了, 就会抛出异常, 需要通过 try...catch 捕获处理;
创建promise对象
const p = new Promise((resolve, reject)=>{
resolve('数据')
})
async function main(){
let result = await p;
console.log(result);
}
main();//数据,await的返回结果就是Promise成功的值。
Object.values、Object.entries和 Object.getOwnPropertyDescriptors:
- Object.values()方法:返回一个给定对象的所有可枚举属性值的数组;
- Object.entries()方法:返回一个给定对象自身可遍历属性 [key,value] 的数组;
- Object.getOwnPropertyDescriptors()该方法:返回指定对象所有自身属性的描述对象;
let school = {
name : "博",
age : 24,
sex : "男"
}
// 获取对象所有的键
console.log(Object.keys(school));
// 获取对象所有的值
console.log(Object.values(school));
// 获取对象的entries
console.log(Object.entries(school));
// 创建map
const map = new Map(Object.entries(school));
console.log(map);
console.log(map.get("name"));
// 返回指定对象所有自身属性的描述对象
console.log(Object.getOwnPropertyDescriptors(school));
// 参考内容:
const obj = Object.create(null,{
name : {
// 设置值
value : "博",
// 属性特性
writable : true,
configuration : true,
enumerable : true
}
});
ES9 新特性
Rest 参数与 spread 扩展运算符
Rest 参数与 spread 扩展运算符在 ES6 中已经引入,不过 ES6 中只针对于数组,在 ES9 中为对象提供了 像数组一样的 rest 参数和扩展运算符;
// Rest参数与spread扩展运算符
// Rest 参数与 spread 扩展运算符在 ES6 中已经引入,
// 不过 ES6 中只针对于数组,在 ES9 中为对象提供了像
// 数组一样的 rest 参数和扩展运算符;
//rest 参数
function connect({host,port,...user}) {
console.log(host);
console.log(port);
console.log(user);
}
connect({
host: '127.0.0.1',
port: 3306,
username: 'root',
password: 'root',
type: 'master'
});
对应属性完成赋值后,username,password,type等后面的值会存在在user里
const skillOne = {
q: '天音波'
w: '金钟罩'
}
// ...skillOne => q: '天音波', w: '金钟罩
//对象合并
const skillOne = {
q: '天音波'
}
const skillTwo = {
w: '金钟罩'
}
const skillThree = {
e: '天雷破'
}
const skillFour = {
r: '猛龙摆尾',
}
const mangseng = {...skillOne,...skillTwo,...skillThree,...skillFour};
console.log(mangseng)
正则扩展:命名捕获分组
ES9 允许命名捕获组使用符号『?』,这样获取捕获结果可读性更强;
// 正则扩展:命名捕获分组
// 声明一个字符串
let str = '<a href="http://www.baidu.com">噫噫噫</a>';
// 需求:提取url和标签内文本
// 之前的写法
const reg = /<a href="(.*)">(.*)</a>/;
// 执行
const result = reg.exec(str);
console.log(result);
// 结果是一个数组,第一个元素是所匹配的所有字符串
// 第二个元素是第一个(.*)匹配到的字符串
// 第三个元素是第二个(.*)匹配到的字符串
// 我们将此称之为捕获
console.log(result[1]);
console.log(result[2]);
// 命名捕获分组
const reg1 = /<a href="(?<url>.*)">(?<text>.*)</a>/;
const result1 = reg1.exec(str);
console.log(result1);
// 这里的结果多了一个groups
// groups:
// text:"噫噫噫"
// url:"http://www.baidu.com"
console.log(result1.groups.url);
console.log(result1.groups.text);
正则扩展:反向断言
ES9 支持反向断言,通过对匹配结果前面的内容进行判断,对匹配进行筛选;
// 正则扩展:反向断言
// 字符串
let str = "JS5201314你知道么555啦啦啦";
// 需求:我们只想匹配到555
// 正向断言
const reg = /\d+(?=啦)/; // 前面是数字后面是啦
const result = reg.exec(str);
console.log(result);
// 反向断言
const reg1 = /(?<=么)\d+/; // 后面是数字前面是么
const result1 = reg.exec(str);
console.log(result1);
正则扩展:dotAll 模式
正则表达式中点.匹配除回车外的任何单字符,标记『s』改变这种行为,允许行终止符出现;
// 正则扩展:dotAll 模式
// dot就是. 元字符,表示除换行符之外的任意单个字符
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>\s+<a>(.*?)</a>\s+<p>(.*?)</p>/;
// dotAll 模式
const reg = /<li>.*?<a>(.*?)</a>.*?<p>(.*?)</p>/gs;
// const result = reg.exec(str);
// console.log(result);
let result;
let data = [];
while(result = reg.exec(str)){
console.log(result);
data.push({title:result[1],time:result[2]});
}
console.log(data);
ES10 新特性
Object.fromEntries
将二维数组或者map转换成对象,之前学的Object.entries是将对象转换成二维数组;
// Object.fromEntries:将二维数组或者map转换成对象
// 之前学的Object.entries是将对象转换成二维数组
// 此方法接收的是一个二维数组,或者是一个map集合
// 二维数组
const result = Object.fromEntries([
["name","小王"],
["age",24],
]);
console.log(result);
const m = new Map();
m.set("name","小王");
m.set("age",24);
const result1 = Object.fromEntries(m);
console.log(result1);
trimStart 和 trimEnd
trimStart:去掉字符串前的空白字符
trimEnd:去掉字符串后的空白字符
Array.prototype.flat 与 flatMap
将多维数组转换成低维数组;
flatMap:如果Map的返回结果是一个多维数组,就可以使用flatMap变成一维数组
Symbol.prototype.description
获取Symbol的描述字符串
ES11 新特性
类的私有属性
私有属性外部不可访问直接
// 类的私有属性
class Person{
// 公有属性
name;
// 私有属性
#age;
#weight;
// 构造方法
constructor(name, age, weight){
this.name = name;
this.#age = age;
this.#weight = weight;
}
intro(){
console.log(this.name);
console.log(this.#age);
console.log(this.#weight);
}
}
// 实例化
const girl = new Person("小兰",18,"90kg");
console.log(girl);
// 公有属性的访问
console.log(girl.name);
// 私有属性的访问
console.log(girl.age); // undefined
// 报错Private field '#age' must be declared in an enclosing class
// console.log(girl.#age);
girl.intro();
Promise.allSettled
获取多个promise执行的结果集
// Promise.allSettled
// 获取多个promise执行的结果集
// 声明两个promise对象
const p1 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("商品数据——1");
},1000);
});
const p2 = new Promise((resolve,reject)=>{
setTimeout(()=>{
reject("失败啦");
},1000);
});
// 调用Promise.allSettled方法
const result = Promise.allSettled([p1,p2]);//成功,失败都可以
console.log(result);
const result1 = Promise.all([p1,p2]); // 注意区别,全部成功才返回
console.log(result1);
String.prototype.matchAll
用来得到正则批量匹配的结果
// String.prototype.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>/sg;
const result = str.matchAll(reg);
// 返回的是可迭代对象,可用扩展运算符展开
// console.log(...result);
// 使用for...of...遍历
for(let v of result){
console.log(v);
}
可选链操作符
如果存在则往下走,省略对对象是否传入的层层判断:?.
// 可选链操作符
// ?.
function main(config){
// 传统写法
// const dbHost = config && config.db && config.db.host;
// 可选链操作符写法
const dbHost = config?.db?.host;
console.log(dbHost);
}
main({
db:{
host:"192.168.1.100",
username:"root"
},
cache:{
host:"192.168.1.200",
username:"admin"
}
});
动态 import 导入
动态导入模块,什么时候使用时候导入:import('要导入文件的路径')
hello.js
export function hello(){
alert('Hello');
}
app.js
// import * as m1 from "./hello.js"; // 传统静态导入
//获取元素
const btn = document.getElementById('btn');
btn.onclick = function(){
import('./hello.js').then(module => {//返回值是一个Promise对象
module.hello();
});
}
BigInt
更大的整数
// BigInt
// 大整型
let n = 100n;
console.log(n,typeof(n));
// 函数:普通整型转大整型
let m = 123;
console.log(BigInt(m));
// 用于更大数值的运算
let max = Number.MAX_SAFE_INTEGER;
console.log(max);
console.log(max+1);
console.log(max+2); // 出错
console.log(BigInt(max));
console.log(BigInt(max)+BigInt(1));//运算时类型要一致
console.log(BigInt(max)+BigInt(2));
globalThis 对象
始终指向全局对象window