目录
ES6新特性
一.let声明变量及特性
- 1.
变量名不能重复声明
(报错,区别于var) - 2.
块级作用域
:如if else for while这些的{}里的内容的let变量都是块级作用域。而es5:全局、函数、eval - 3.
不存在变量提升
(变量不能提前声明,区别于var) - 4.
不影响作用域链
(找不到变量,会沿着离其最近的块级作用域寻找变量)
<body>
<script>
// 声明变量
let a;
let b, c;
let g = 'hhhh', f = 555;
// let变量特点
// 1.变量名不能重复声明(报错)
// let d = e;
// let d = 3;
// 2.块级作用域:如if else for while这些的{}里的内容的let变量都是块级作用域 es5:全局、函数、eval
{
let d = 4;
console.log(d); //值为4.
}
//console.log(d); //报错,找不到d变量的定义。因为是d块级作用域
// 3.不存在变量提升(变量不能提前声明,区别于var)
// console.log(e);
// let e = 2; //报错,e没有提前声明,变量不会提升
// 4.不影响作用域链(找不到变量,会沿着离其最近的块级作用域寻找变量)
{
let r = "你好";
function fun() {
console.log(r); //在fun里找不到r,会沿着fun()外最近的找
}
fun();
}
</script>
</body>
二、const常量
特点:
- 1.要赋予初始值,且定义的常量名不能重复
- 2.常量值不能修改
- 3.一般常量名要大写(潜规则)
- 4.块级作用域
- 5.对数组和对象的元素修改,不算做对常量的修改,不会报错
<script>
// 声明常量
const a = '小写';
console.log(a);
// 特点:1.要赋予初始值,且定义的常量名不能重复
// 2.常量值不能修改
// 3.一般常量名要大写(潜规则)
// 4.块级作用域
// {
// const NA = '嘻嘻';
// }
// console.log(NA); //报错,找不到NA这个常量
// 5.对数组和对象的元素修改,不算做对常量的修改,不会报错
const TEAM = ['l', 'ed', 'egh'];
TEAM.push('wlg');
console.log(TEAM);
const ONE = { name: 6, bag: 23 };
ONE.hh = 'hddg';
ONE.name = 'hhh';
console.log(ONE);
</script>
三、变量的解构赋值
- ES6 允许按照一定模式从数组和对象中提取值,对变量进行赋值----解构赋值
<script>
// 1.数组的解构
const LIST = ['北北', '京京', '欢欢', '迎迎', '昵昵'];
let [bei, jing, huan, ying, ni] = LIST;
console.log(bei);
console.log(jing);
console.log(huan);
console.log(ying);
console.log(ni);
// 2.对象的解构
const OBJECT = {
name: '小沙',
age: 53,
test: function () {
console.log('你是谁');
}
};
let { name, age, test } = OBJECT;
console.log(name);
console.log(age);
console.log(test);
test();
</script>
四、反引号``
- ES6 引入新的声明字符串的方式 反引号``
- 2.内容中可以直接出现换行符(单/双引号不可以)
- 3.变量拼接
${变量名}
<script>
// 1、声明
let str = `我也可以表示一个字符串`;
console.log(str, typeof str);
// 2.内容中可以直接出现换行符(单/双引号不可以)
let li = `<ul>
<li> 马里奥</li>
<li>阿甘</li>
<li>慧丽</li>
</ul >`;
console.log(li);
// 3.变量拼接 ${变量名}
let name = '罗翔';
let finaly = `${name}是一个无比厉害的人`;
console.log(finaly);
</script>
五、对象
5.1 对象的简写形式
- ES6 允许在大括号中,直接写入变量和函数,作为对象的属性和方法
<script>
// ES6 允许在大括号中,直接写入变量和函数,作为对象的属性和方法
let name = 'HHHH';
let age = function () {
console.log("你多大了");
};
const One = {
name, //等同:name:name;
age, //等同:age:age;
level() { //等同: level: function(){}
console.log("提高水平");
}
}
console.log(One);
</script>
5.2 对象方法的扩展
- 1.
Object.is
判断两个值是否完全相等,类似但不完全与 全等(===)一样 - 2.
Object.assign(被覆盖的对象,覆盖的对象)
对象的合并 - 3.
Object.setPrototypeOf
设置原型对象Object.getPrototypeOf
获取原型对象
<script>
// 1.Object.is 判断两个值是否完全相等,类似但不完全与 全等(===)一样
console.log(Object.is(100, 100)); //true
console.log(Object.is(NaN, NaN)); //true
console.log(NaN === NaN); //false
// 2.Object.assign(被覆盖的对象,覆盖的对象) 对象的合并
const one = {
name: '上',
age: 30,
gender: '女',
friends: 9
};
const two = {
name: '下',
age: 20
};
console.log(Object.assign(one, two));
// 3.Object.setPrototypeOf设置原型对象 Object.getPrototypeOf获取原型对象
// 一般不建议写
const zero = {
name: '慧慧'
};
const finall = {
oo: [1, 4, 5, 6, 3]
};
Object.setPrototypeOf(zero, finall);
console.log(zero);
console.log(Object.getPrototypeOf(zero));
</script>
六、箭头函数的声明与特性
- ES6允许使用箭头(
=>
)定义函数 - 特性
- 1.
this是静态的
,this始终指向函数声明时所在作用域下的this的值 - 2.
不能
作为构造函数实例化对象 - 3.
不能
用arguments
变量 - 4.箭头函数的简写
1)省略小括号
,当形参有且只有一个时
2)省略花括号
,当代码只有一条语句时,此时return必须省略,且语句的执行结果就是函数的返回值
<script>
// ES6允许使用箭头(=>)定义函数
// 声明一个函数
// 这是普通的函数声明方式
// let fn = function () {
// }
// 这是箭头函数的声明方式
let fn = (a, b) => {
return a + b;
}
// 调用函数
console.log(fn(1, 3));
// 箭头函数的特性
// 1.this是静态的,this始终指向函数声明时所在作用域下的this的值
function getName() {
console.log(this.name);
}
let getName2 = () => {
console.log(this.name);
}
// 设置window 对象的name
window.name = '哈哈哈';
const ONE = {
name: "LAT"
}
// 直接调用
getName(); //哈哈哈
getName2(); //哈哈哈
// call 方法调用
getName.call(ONE); //LAT
getName2.call(ONE); //哈哈哈
// 2.不能作为构造函数实例化对象
// let Person = (name, age) => {
// this.name = name;
// this.age = age;
// }
// let me = new Person('xia', 10);
// console.log(me); //报错,不能作为构造函数实例化对象
// 3.不能用arguments变量
// let fn = () => {
// console.log(arguments); //arguments未被定义(报错)
// }
// fn(1);
// 4.箭头函数的简写
// 1)省略小括号,当形参有且只有一个时
let add = n => {
return n + n;
}
console.log(add(3));
// 2)省略花括号,当代码只有一条语句时,此时return必须省略,且语句的执行结果就是函数的返回值
let two = m => m * m;
console.log(two(6));
</script>
七、函数参数的默认值设置
- 可以给函数参数赋初始值
- 1.形参初始值(具有默认值的参数)一般位置要靠后
- 2.与解构赋值结合
<script>
// 可以给函数参数赋初始值
// 1.形参初始值(具有默认值的参数)一般位置要靠后
function fun(a, b, c = 5) {
return a + b + c;
}
console.log(fun(1, 7));
// 2.与解构赋值结合
function connect({ host, username, password, port }) {
console.log(host);
console.log(username);
console.log(password);
console.log(port);
}
connect({
host: '192.168.1.1',
username: 'user',
password: 13464,
port: 80
})
</script>
八、rest参数
- ES6 引入
rest
参数,用于获取函数的实参,用来代替arguments.只针对数组
- rest参数(ES6),
形参名
必须为:...args
- rest参数必须放在最后
<script>
// ES6 引入rest参数,用于获取函数的实参,用来代替arguments
// ES5 用arguments获取参数,如下
// function date() {
// console.log(arguments);
// }
// date('小花', '小米', '小熊'); //结果为一个对象,而不是数组
// rest参数(ES6),形参名必须为:...args
function date(...args) {
console.log(args);
}
date('小花', '小米', '小熊'); //结果是数组,具体为:(3) ['小花', '小米', '小熊']0: "小花"1: "小米"2: "小熊"length: 3[[Prototype]]: Array(0)
// rest参数必须放在最后
function fn(a, b, ...args) {
console.log(a); //2
console.log(b); //3
console.log(args); //(5) [6, 3, 6, 78, 5]
}
fn(2, 3, 6, 3, 6, 78, 5);
</script>
九、扩展运算符
...
扩展运算符能将 数组 转换为逗号分隔的 参数序列
应用- 1.数组的合并
- 2.数组的克隆
- 3.将伪数组转化为真数组
<script>
// 【...】扩展运算符能将 数组 转换为逗号分隔的 参数序列
const name = ['虾皮', '喜哥', '水果捞'];
function fun() {
console.log(arguments);
}
fun(...name); //('虾皮', '喜哥', '水果捞')
// 应用
// 1.数组的合并
const one = ['下', '上'];
const two = ['回', '来'];
// const end = one.concat(two); //以前的写法,现在用扩展运算符写,如下
const end = [...one, ...two];
console.log(end);
// 2.数组的克隆
const single = ['哈哈', '嘻嘻', '哦哦'];
const double = [...single];
console.log(double);
// 3.将伪数组转化为真数组
const divs = document.querySelectorAll("div");
const divArr = [...divs];
console.log(divArr);
</script>
十、Symbol
十一、迭代器
11.1迭代器的介绍
- 迭代器(
Iterator
)是一种接口,为不同的数据结构提供统一的访问机制 - 任何数据结构只要部署
Iterator接口(对象中的一个属性==Symbol.iterator)
,就可以完成遍历操作(主要用for...of
)
<script>
// 任何数据结构只要部署Iterator接口(对象中的一个属性==Symbol.iterator),就可以完成遍历操作(主要用for...of)
const name = ['嘻嘻', '哈哈', '娃娃'];
// 用 for ...of 遍历数组
// for (let v of name) {
// console.log(v);
// }
let iterator = name[Symbol.iterator]();
// 调用对象的next方法
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
</script>
11.2 迭代器的工作原理
<script>
// 迭代器的底层原理(工作原理)
const one = {
name: "第一",
stus: [
"星星",
"夏夏",
"乐乐",
"可可"
],
[Symbol.iterator]() {
// 索引变量
let index = 0;
return {
next: () => {
if (index < this.stus.length) {
const result = { value: this.stus[index], done: false };
index++;
return result;
} else {
return { value: undefined, done: true };
}
}
}
}
};
// 遍历这个对象
for (let v of one) {
console.log(v);
}
</script>
十二、生成器(实现异步编程)
- 生成器其实就是一个特殊的函数
- 作用:
异步编程
解决方案(纯回调函数) [node fs ajax mongodb解决
:套娃后->回调地狱
]
<script>
// 创建一个生成器
// function* gen() {
// console.log("hello");
// }
// // 执行
// let iterator = gen();
// // console.log(iterator); //gen
// iterator.next(); //hello
// 函数代码的分隔符
function* gen() {
// console.log(1);
yield '去吧';
// console.log(2);
yield '配吗';
// console.log(3);
yield '这褴褛的衣裳';
// console.log(4);
}
let iterator = gen();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
// 遍历
// for (let v of gen()) {
// console.log(v);
// }
</script>
- 可以进行参数传递
<script>
function* gen(arg) {
console.log(arg);
let one = yield 11;
console.log(one);
let two = yield 22;
console.log(two);
let three = yield 33;
console.log(three);
}
// 获取迭代器对象
let iterator = gen('aaa');
console.log(iterator.next());
// next方法可以传入参数
console.log(iterator.next('AAA'));
console.log(iterator.next('BBB'));
console.log(iterator.next('CCC'));
</script>
十三、Promise(面试重点,实现异步编程,解决回调地狱问题)
Promise
是ES6引入的异步编程
的新解决方案。语法上是一个构造函数
,来封装异步操作并可以获取其成功或失败
的结果语法:new Promise(function(resolve,reject){})
- 调用promise对象的
then方法
catch方法
<script>
// 实例化Promise对象
let p = new Promise(function (resolve, reject) {
setTimeout(function () {
// let data = "数据库中的内容";
// resolve(data);
let err = "信息有误";
reject(err);
}, 1000);
});
// 调用promise对象的then方法
// p.then(function (value) {
// console.log(value);
// }, function (reason) {
// console.log(reason);
// })
// catch方法
p.catch(function (reason) {
console.warn(reason);
})
</script>
- Promise封装读取文件
// 1.引入fs模块
const fs = require('fs');
// // 2.调用方法读取文件
// fs.readFile('./例子.md', (err, data) => {
// // 如果失败,则抛出异常
// if (err) throw err;
// // 如果没有出错,则输出内容
// console.log(data.toString());
// });
// 3.用promise封装
const p = new Promise(function (resolve, reject) {
fs.readFile("./例子.md", (err, data) => {
// 判断如果失败
if (err) reject(err);
// 如果没有出错
resolve(data);
});
});
p.then(function (value) {
console.log(value.toString());
}, function (reason) {
console.log("读取失败!!!");
})js
- Promise读取多文件
// 引入fs模块
const fs = require("fs");
const { resolve } = require("path");
// 读取多个文件(这样就形成回调地狱,不建议)
// fs.readFile('./辛夷坞.md', (err, data1) => {
// fs.readFile('./春夜洛阳城闻笛.md', (err, data2) => {
// fs.readFile('./卜算子.md', (err, data3) => {
// let result = data1 + '\n' + data2 + '\n' + data3;
// console.log(result);
// });
// });
// });
const p = new Promise((resolve, reject) => {
fs.readFile("./辛夷坞.md", (err, data) => {
resolve(data);
});
});
p.then(value => {
return new Promise((resolve, reject) => {
fs.readFile("./卜算子.md", (err, data) => {
resolve([value, data]);
});
});
}).then(value => {
return new Promise((resolve, reject) => {
fs.readFile("./春夜洛阳城闻笛.md", (err, data) => {
value.push(data);
resolve(value);
});
});
}).then(value => {
console.log(value.join("\n"));
});
十四、Set集合
14.1集合简介
- ES6 提供了新的数据结构
Set(集合)
,类似数组,但成员值唯一。实现了iterator接口,可以用扩展运算符
和for...of进行遍历
。
集合的属性和方法
- 1.
size属性
返回集合的元素个数 - 2.
add方法
增加一个新元素,返回当前元素集合 - 3.
delete方法
删除元素,返回boolean值 - 4.
has方法
检测集合中是否包含某个元素,返回boolean值 - 5.
clear方法
,清空集合
<script>
// ES6 提供了新的数据结构Set(集合),类似数组,但成员值唯一。实现了iterator接口,可以用扩展运算符和for...of进行遍历。
// 声明一个set
let s = new Set();
console.log(s, typeof s); //set也是一个对象
let s1 = new Set(['小小', '大大', '丽丽', '芹芹']);
// 集合的属性和方法
// 1.size属性 返回集合的元素个数
console.log(s1.size);
// 2.add方法 增加一个新元素,返回当前元素集合
s1.add('西西');
// 3.delete方法 删除元素,返回boolean值
s1.delete('小小');
// 4.has方法 检测集合中是否包含某个元素,返回boole值
console.log(s1.has('西西'));
// 5.clear方法,清空集合
// s1.clear();
console.log(s1);
// 遍历集合
for (let v of s1) {
console.log(v);
}
</script>
14.2 集合基本运算
- 1.数组去重
- 2.交集
- 3.并集
- 4.差集
<script>
let arr = [1, 2, 5, 76, 83, 6, 7, 3, 3, 4, 5];
let arr2 = [3, 4, 5, 56, 77];
// 1.数组去重
let result = [...new Set(arr)];
// 2.交集
// result = [...new Set(arr)].filter(item => {
// let s = new Set(arr2);
// if (s.has(item)) {
// return true;
// } else {
// return false;
// }
// });
// 上面的内容可以简写为
result = [...new Set(arr)].filter(item => new Set(arr2).has(item));
// 3.并集
result = [...new Set([...arr, ...arr2])];
// 4.差集
result = [...new Set(arr)].filter(item => !new Set(arr2).has(item));
console.log(result);
</script>
十五、Map
ES6 提供了Map
数据结构,类似对象,也是键值对的集合
。但是“键”的可以是任意数据类型的(包括对象)。 Map也实现了iterator接口,可以用扩展运算符
和for...of进行遍历
。
Map的属性和方法
- 1.
size属性
返回Map的元素个数 - 2.
set方法
增加一个新元素,返回当前Map - 3.
get方法
返回键名对象的键值 - 4.
has方法
检测Map中是否包含某个元素,返回boolean值 - 5.
clear方法
,清空集合,返回undefined
<script>
let m = new Map();
// set()方法,添加Map元素
m.set('name', '值');
m.set('method', function () {
console.log("Map的值也可以是一个方法");
})
let obj = {
name: "对象",
value: 2
};
m.set('obj', "Map的键也可以是对象");
console.log(m);
// size
console.log(m.size);
// get
console.log(m.get('name'));
// has
console.log(m.has('name'));
//clear
// m.clear();
// console.log(m);
// 遍历
for (let v of m) {
console.log(v);
}
</script>
十六、class(类)
16.1 class简介
作用:class写法可让对象原型的写法更清晰、更像面向对象编程的语法。
- 1.
class语法: class 类名{}
- 2.
定义构造函数初始化 constructor(){}
名字不能改 class不一定必须出现构造函数 - 3,
方法
必须用call(){}语法
,不能用ES5的对象完整形式
<script>
// ES5 里的写法
// function Phone(brand, price) {
// this.brand = brand;
// this.price = price;
// }
// // 添加方法
// Phone.prototype.call = function () {
// console.log("这是手机");
// }
// // 实例化对象
// let Xiaomi = new Phone('小米', 5000);
// Xiaomi.call();
// console.log(Xiaomi);
// ES6中 class写法
class Phone {
// 构造方法 名字不能改
constructor(brand, price) {
this.brand = brand;
this.price = price;
}
// 方法必须用call(){}语法,不能用ES5的对象完整形式
call() {
console.log("这是手机");
}
}
let Xiaomi = new Phone('小米', 4000);
console.log(Xiaomi);
Xiaomi.call();
</script>
16.2 class静态成员
<script>
// function Phone() {
// }
// Phone.name = '华为'; //函数对象
// Phone.change = function () { //函数对象
// console.log("是这个方法");
// };
// Phone.prototype.size = "6.1inch"; //函数原型对象,这个可以和实例对象想通,因为原型问题
// let huawei = new Phone(); //实例对象
// // 下面这两个例子证明,函数对象和实例对象的属性不同,也说明,函数对象是静态的。在class类中就是静态成员
// console.log(huawei.name); //undefined
// // huawei.change(); //报错,找不到该方法
// console.log(huawei.size); //6.1inch
class Phone {
//静态成员
static name = '华为';
static change = function () {
console.log("是方法");
};
}
let huawei = new Phone();
console.log(huawei.name); //undefined
console.log(Phone.name); //华为
</script>
16.3 类继承
<script>
// 父类函数
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); //相当于:Phone.call(this,brand,price);
this.color = color;
this.size = size;
}
// 子类特有方方法
photo() {
console.log("子类的拍照功能");
}
playGame() {
console.log("子类的游戏功能");
}
// 子类对父类的重写。只能通过子类读取子类的重写方法,不能通过子类读取父类的重写方法
call() {
console.log("我是子类中的call方法,是对父类的重写");
}
}
// 实例化子类
const huawei = new SmartPhone('华为', 5000, '香芋紫', '6.1 inch');
console.log(huawei);
// huawei.call();
// huawei.photo();
// huawei.playGame();
</script>
16.4 class中get和set设置
class Phone {
// get适用动态获取数据
// get会获取该函数下的内容,并且有return时有返回返回值,没有则返回undefinded
get price() {
console.log("获取了价格属性");
return 111;
}
// set可以通过修改该方法下的信息,从而调用该方法。如代码28行,会使得执行21-24行
set price(newValue) {
console.log('修改价格属性');
}
}
// 实例化对象
let s = new Phone();
console.log(s.price);
s.price = '33333dbh';
十七、数值扩展
- 1.
Number.EPSILON
是javascript表示的最小精度 - 2.二进制、十进制、八进制、十六进制
- 3.
Number.isFinite
检测一个值是否是有限数 - 4.
Number.parseInt
字符串转整数 Number.parseFloat 字符串转浮点数 - 5.
Number.isInteger
判断一个数是否为整数 - 6.
Math.trunc
将数字的小数部分抹掉 - 7.
Math.sign
判断一个数到底为正数 负数还是零
<script>
// 1.Number.EPSILON是javascript表示的最小精度
function equal(a, b) {
if (Math.abs(a - b) < Number.EPSILON) {
return true;
} else {
return false;
}
}
console.log(equal(0.1 + 0.3, 0.4));
// 2.二进制、十进制、八进制、十六进制
let a = 0b0010;
let b = 200;
let c = 0o33;
let d = 0x2f;
console.log(a);
console.log(b);
console.log(c);
console.log(d);
// 3.Number.isFinite 检测一个值是否是有限数
console.log(Number.isFinite(3));
console.log(Number.isFinite(-2));
console.log(Number.isFinite(Infinity));
// 4.Number.parseInt 字符串转整数 Number.parseFloat 字符串转浮点数
console.log(Number.parseInt('55274dag'));
console.log(Number.parseFloat('2.356fd'));
// 5.Number.isInteger判断一个数是否为整数
console.log(Number.isInteger(4.2));
// 6.Math.trunc将数字的小数部分抹掉
console.log(Math.trunc(2.5432));
// 7.Math.sign判断一个数到底为正数 负数还是零
console.log(Math.sign(500)); // 1
console.log(Math.sign(-111)); //-1
console.log(Math.sign(0)); //0
</script>
十八、模块化
18.1 模块化概念
:将一个大的程序文件拆分成多个小文件,再将小文件组合起来
18.2 优点:
1.防止命名冲突
2.代码复用
3.高维护性
18.3 模块化产品规范
18.4 ES6模块化语法
模块化功能主要由2个命令构成: export
import
-
export
命令用于规定模块化的对外接口 -
import
命令用于输入其他模块提供的功能
1、在html页面引入
模块化语法有3种
形式,分别为以下代码的方式一和方式二
以及项目常用的babel转换
2、对于如何导入
js文件中的模块化有3种
方式,暴露形式也有3种
形式分别为: -
2.1.1
通用形式
导入模块化 -
2.1.2
解构赋值形式
导入模块化 -
2.1.3
简便形式
,只针对默认暴露 -
2.2.1
分别暴露
-
2.2.2
统一暴露
-
2.2.3
默认暴露
<!-- 一引入模块化方式一 -->
<script type="module">
//1. 通用形式导入模块化
// 导入 模块化1 模块化
import * as m1 from "../js/模块化1.js";
console.log(m1);
// 导入 模块化2 模块化
import * as m2 from "../js/模块化2.js";
console.log(m2);
// 导入 模块化3 模块化
import * as m3 from "../js/模块化3.js";
console.log(m3);
// 2.解构赋值形式 导入模块化
import { name, methods } from "../js/模块化1.js";
console.log(name, methods);
import { name as n, way } from "../js/模块化2.js";
console.log(n, way);
// 默认暴露的解构赋值形式 必须写default
import { default as m4 } from "../js/模块化3.js";
console.log(m4);
// 3.简便形式,只针对默认暴露
import m5 from "../js/模块化3.js";
console.log(m5);
</script>
<!-- 二引入模块化方式二,较常用 -->
<script type="module" src="../js/app.js"></script>
// 模块化1.js
// 分别暴露
export let name = "分别暴露";
export function methods() {
console.log("模块化的分别暴露形式");
}
// 模块化2.js
// 统一暴露
let name = "统一暴露";
function way() {
console.log("统一暴露");
}
export { name, way };
// 模块化3.js
// 默认暴露
export default {
name: "默认暴露",
means: function () {
console.log("模块化中的默认暴露形式");
}
}
// app.js
import * as m1 from "../js/模块化1.js";
import * as m2 from "../js/模块化2.js";
import * as m3 from "../js/模块化3.js";
console.log(m1);
console.log(m2);
console.log(m3);
ES7新特性
includes
方法和**
指数操作符
- includes 检测数组中是否存在某个元素。作用同indexOf
- **指数运算符,用来操作幂运算,相当于Math.pow
<script>
// 1.includes 检测数组中是否存在某个元素。作用同indexOf
const game = ['篮球', '足球', '羽毛球', '橄榄球'];
console.log(game.includes('篮球')); //true
console.log(game.indexOf('篮球')); //0 indexOf返回的是数组下标,没有则返回-1
// 2. **指数运算符,用来操作幂运算,相当于Math.pow
console.log(2 ** 3); //8
console.log(Math.pow(2, 3)); //8
</script>
ES8新特性
一. async函数(异步编程解决方案)和await表达式
1.1 async函数和await表达式
async函数和await表达式两种语法的结合可以让异步代码像同步代码一样
1.2 async函数
- 1.返回值是
promise对象
- 2.promise对象的
结果
由async函数执行的返回值决定(其中,如果返回的结果不是一个promise类型的对象,则async函数返回的结果就是成功的promise对象,具体看代码解析)
<script>
async function fn() {
//返回一个字符串
// return '这是一个async函数';
// 如果返回的结果不是一个promise类型的对象,则fn()返回的结果就是成功的promise对象
// return;
// 抛出错误,fn()返回的结果是一个失败的promise对象
// throw new Error('出错啦');
// 返回的结果如果是一个promise对象
return new Promise((resolve, reject) => {
// resolve('返回的结果本身是一个promise对象,fn()返回结果是成功的promise对象');
reject('返回的结果本身是一个promise对象,fn()返回结果是失败的promise对象')
})
}
const result = fn();
console.log(result);
</script>
1.3 await表达式
- await必须放在async函数中
- await右侧的表达式一般是
promise对象
- 返回的是promise成功的值
- await的promise失败的话,需要用
try...catch捕获异常
<script>
// 创建一个promise对象
const p = new Promise((resolve, reject) => {
// resolve('获取到正确的结果');
reject('出错了');
})
// await必须放在async中
async function fn() {
// try...catch捕获异常
try {
let result = await p;
console.log(result);
} catch (e) {
console.log(e);
}
}
// 调用函数
fn();
</script>
二.对象方法扩展
Object.keys()
获取对象的所有键Object.values()
获取对象的所有值(返回的是一个数组)Object.entries()
获取对象自身可遍历属性[keys,value]的数组,可以通过Object.entries形成的键值对数组,生成MapObject.getOwnPropertyDescriptors()
返回指定对象所有自身属性的描述对象
<script>
// 声明对象
const all = {
name: '好样的',
arr: ['春', '秋', '夏', '冬'],
position: ['码农', '负责人', '经理', '董事长']
};
// 获取对象的所有键
console.log(Object.keys(all));
// 获取对象的所有值(返回的是一个数组)
console.log(Object.values(all));
// Object.entries获取对象自身可遍历属性[keys,value]的数组
console.log(Object.entries(all));
// 可以通过Object.entries形成的键值对数组,生成Map
const m = new Map(Object.entries(all));
console.log(m);
console.log(m.get('arr'));
// 返回指定对象所有自身属性的描述对象
console.log(Object.getOwnPropertyDescriptors(all));
</script>
ES9
一、扩展运算符和rest参数
rest 参数与spread扩展运算符在ES6中就引入,但只针对数组。ES9中可以为 对象
提供这个功能
<script>
// rest 参数与spread扩展运算符在ES6中就引入,但只针对数组。ES9中可以为 对象 提供这个功能
function connect({ host, port, ...user }) {
console.log(host);
console.log(port);
console.log(user);
}
connect({
host: '192.168.1.1',
port: 80,
username: 'root',
password: '3332113'
});
const chun = { c: '春天' };
const xia = { x: '夏天' };
const qiu = { q: '秋天' };
const dong = { d: '冬天' };
const season = { ...chun, ...xia, ...qiu, ...dong };
console.log(season);
</script>
二、正则表达式
2.1 命名捕获分组
<script>
// // 声明一个字符串
// let str = '<a href="https://www.baidu.com">百度</a>'
// // 提取url与标签文本
// const reg = /<a href="(.*)">(.*)<\/a>/;
// // 执行
// const result = reg.exec(str);
// console.log(result);
// console.log(result[2]); //百度
// console.log(result.groups); //undefined
// 声明一个字符串
let str = '<a href="https://www.baidu.com">百度</a>'
// 提取url与标签文本
const reg = /<a href="(?<url>.*)">(?<text>.*)<\/a>/;
// 执行
const result = reg.exec(str);
console.log(result);
console.log(result[2]); //百度
console.log(result.groups); // {url: 'https://www.baidu.com', text: '百度'}
console.log(result.groups.url); // https://www.baidu.com
</script>
2.2 反向、正向断言
<script>
// 声明字符串
let str = 'hejg22377975不好意思啊哈哈哈3hgjang35ui2';
// // 正向断言
// const reg = /\d+(?=不好)/;
// const result = reg.exec(str);
// console.log(result);
// 反向断言
const reg = /(?<=g)\d+/;
const result = reg.exec(str);
console.log(result);
</script>
2.3 dotAll模式(.代表任意字符)
- dot 即. (元字符),它可以匹配除了 换行符(\n)、回车符(\r)、行分隔符、段分隔符、四个字节的UTF-16字符外的任意字符。所以引入
dotAll,使得.可以匹配任意字符
<script>
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>.*?<\/li>/gs;
// 执行匹配
// const result = reg.exec(str);
// console.log(result);
let result;
let data = [];
while (result = reg.exec(str)) {
data.push({ title: result[1], time: result[2] });
}
console.log(data);
</script>
三、Object.fromEntries(iterable)把键值对转换为对象
Object.fromEntries(iterable)
用于将键值对
列表转换为对象。此方法返回一个新对象
,其属性由iterable的条目确定
。(同理Object.fromEntries可以把二维数组转换为(键值对)对象)
<script>
// 二维数组
const result = Object.fromEntries([
['name', '二维数组'],
['way', '把二维数组转换为对象']
]);
console.log(result);
// Map
const m = new Map();
m.set('name', 'Map');
const end = Object.fromEntries(m);
console.log(end);
// Object.entries将对象转换为二维数组(ES8)
const arr = Object.entries({
name: '对象'
});
console.log(arr);
</script>
四、扩展对象方法trimStart
和trimEnd
- trimStart 删去对象(字符串)左侧空白
- trimEnd 删去对象(字符串)右侧空白
<script>
// trimStart 删去对象(字符串)左侧空白
let str = ' 删空白的方法 ';
console.log(str);
console.log(str.trimStart());
console.log(str.trimEnd());
// trimEnd 删去对象(字符串)右侧空白
</script>
五、数组的扩展方法flat
和flatMap
flat(n)
将多维数组转化为低维数组,n为深度(降低的数组维度数)flat(Infifity);
直接降为一维数组flatMap()
只能展开一层
数组
<script>
// flat() 将多维数组转化为低维数组
const arr = [1, 24, 5, [1, 45, 3, [5, 3]]];
console.log(arr);
// flat(n),n为深度(降低的数组维度数)
console.log(arr.flat(2)); //3维降到1维,3-1=2
// flatMap()只能展开一层数组
const arr1 = [1, 3, 6];
const result = arr1.flatMap(item => [item * 10]);
console.log(result);
</script>
ES 10
1.symbol.prototype.description
获取symbol的字符串描述
<script>
// 创建symbol
let s = Symbol('描述');
console.log(s.description);
</script>
ES11
一、私有属性
- 私有属性不能在类外被访问。
- 可以通过调用类内的一个方法,实现在类外访问私有属性
<script>
// 定一个类
class Person {
// 公有属性
name;
// 私有属性 #
#age;
#weight;
// 构造方法
constructor(name, age, weight) {
this.name = name;
this.#age = age;
this.#weight = weight;
}
// 可以通过调用类内的一个方法,实现在类外访问私有属性
siyou() {
console.log(this.name);
console.log(this.#age);
console.log(this.#weight);
}
}
// 实例化对象
const girl = new Person('丽丽', 10, '40kg');
console.log(girl);
// console.log(girl.#age); //报错,私有属性不能在类外被访问。
girl.siyou();
</script>
二、Promise.allSettled()
Promise.allSettled()
返回的一直
都是promise成功的状态
,但是具体的结果根据promise的具体值显示Promise.all()
只有
涉及的promise都是成功的,状态才是成功的,输出结果也是成功的结果,否则状态都是失败状态,只会输出失败的结果
<script>
// 声明两个promise
const one = new Promise((resolve, reject) => {
setTimeout(() => {
// resolve('正确值1');
reject('出错了1');
}, 1000)
});
const two = new Promise((resolve, reject) => {
setTimeout(() => {
// resolve('正确值2');
reject('出错了2');
}, 1000)
});
// 调用allsettled方法
const result = Promise.allSettled([one, two]);
// 调用all方法。Promise.all()只有涉及的promise都是成功的,状态才是成功的,输出结果也是成功的结果,
// 否则状态都是失败状态,只会输出失败的结果
const end = Promise.all([one, two]);
console.log(result);
console.log(end);
</script>
三、string.matchAll(正则表达式)
string.matchAll(正则表达式)
字符串扩展,用于正则匹配提取数据
<script>
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>.*?<\/li>/gs;
// 调用方法
const result = str.matchAll(reg);
// console.log(result);
// for (let v of result) {
// console.log(v);
// }
const arr = [...result]; //将提取出的数据通过扩展运算符存放到一个新数组中
console.log(arr);
</script>
四、可选链操作符 ?.
<script>
// ?.
function fn(config) {
// const dbName = config && config.db && config.db.name;
const dbName = config?.db?.name;
console.log(dbName);
}
fn({
db: {
name: '主子',
age: 30
},
other: {
name: '仆人',
age: 40
}
})
</script>
五、动态获取import
- 动态获取import(性能更高)
<!--动态import.html-->
<body>
<button id="btn">按钮</button>
<script src="../es11/app.js" type="module"></script>
</body>
//app.js
// 静态import
// import * as m1 from "../es11/fn.js";
// 获取元素
const btn = document.getElementById("btn");
btn.onclick = function () {
// 动态获取import(性能更高)
import('../es11/fn.js').then(module => {
module.fn();
});
}
//fn.js
export function fn() {
alert('动态获取import');
}
六、大整型BigInt
(又一个数据类型)
<script>
//大整型,也是一个数据类型
let n = 33n;
console.log(n, typeof (n)); //33n 'bigint'
// 函数
let a = 442;
console.log(BigInt(a)); //442n
// console.log(BigInt(3.4)); //报错,不是一个整数
// 大数值运算
let max = Number.MAX_SAFE_INTEGER;
console.log(max); //9007199254740991
console.log(max + 1); //9007199254740992
console.log(BigInt(max)); //9007199254740991n
console.log(BigInt(max) + BigInt(1)); //9007199254740992n
</script>
七、全局属性globalThis
- 全局属性globalThis包含全局的this值,类似于全局对象(Global object);
<script>
console.log(globalThis);
</script>