ES
优点
- 语法简洁,功能丰富
- 框架开发应用
- 前端开发职位要求
ES6
let 变量声明
1.let变量不能重复声明
let star = 'ronald';
let star = 'aaa'; //会报错
2.块级作用域
{
let girl = 'ronald'
}
console.log(girl);//会报错
3.不存在变量提升
console.log(song); //song is not defined
let song = '恋爱达人';
console.log(song); //undefined,不会报错
var song = '恋爱达人';
4.不影响作用域链
let song = '恋爱达人';
function fn(){
console.log(song);
}
fn(); //恋爱达人
const常量
- 一定要赋值初始值
- 一般常量使用大写
- 常量值不能被修改
- 块级作用域
- 对于数组和对象的元素修改,不算做对常量的修改,不会报错
const ar = ['UZI','MLXG','MING'];
ar[0] = 'ronald'; //可以修改成功
解构赋值
数组的解构
const f4 = ['小沈阳','liuneng','zhaosi'];
let [a,b,c,d] = f4;
console.log(a); //小沈阳
对象的解构
const user = {
name : 'roanld',
age : 18,
lesson : {
lessonName : 'Math'
}
}
let {name,age,{lessonName}} = user;
console.log(name); //ronald
console.log(age); //18
console.log(lessonName); //Math
模板字符串
- 声明
let title = `我叫成龙`;
- 内容中可以直接出现换行符
let str = `<ul>
<li>1</li>
<li>2</li>
</ul>
`
- 变量拼接
let name = 'ronald';
let title = `我叫${name}`; //我叫ronald
对象的简化写法
let name = 'ronald';
let age = 18;
let obj = {
name,
age
}
箭头函数 =>
let fn = function(){
}
let fn = (a,b)=>{
return a+b
}
let result = fn(2,4); // 6
1.this 是静态的,this始终指向函数声明时所在作用于下的this的值
2.不能作为构造实例化对象
3.不能使用arguments变量
let fn = ()=>{
console.log(arguments); //报错 arguments is not defined
}
fn(1,2,3);
4.箭头函数的简写
//1.省略小括号,当形参有且只有一个的时候
let add = n =>{
n++;
}
console.log(add(9));
//2 省略花括号,当代码题只有一条语句的时候,return必须省略,而且语句执信结果就是函数的返回值
let pow = n => n*2;
5.箭头函数适合与this无关的回调,定时器,数组的方法回调等,不适合事件回调、对象的方法
函数参数默认值
es6允许给函数参数赋值初始值
//1 形参初始值,具有默认值的参数一般放后面
function add (a,b,c=10){
return a+b+c
}
let result = add(1,2);
console.log(result)
//2 与解构赋值结合
function connect({host,username,pwd}){
console.log(host)
console.log(username)
console.log(pwd)
}
connect({
host : 'http://www.baidu.com',
username : 'roanld',
pwd:'abc123'
})
rest参数
ES6引入rest参数用于获取函数的实参,用来代替arguments,rest参数必须要放在最后
function date(a,b,...rest){
console.log(a)
console.log(b)
console.log(rest); //['alin','tommon']
}
date('ronald','simon','alin','tommon');
扩展运算符
const tfboys = ['a','b','c'];
let users = ['aaa',...tfboys]; //['aaa','a','b','c']
Symbol
Symbol是新赠的第七个基础数据类型, 基础数据类型分别是(简单记忆是有USONB)
- U:undefined
- S: Symbol string
- O: object
- N : null number
- B : Boolean
- Symbol的值是唯一的,用来解决命名冲突的问题
- Symbol的值不能与其他数据进行运算
- Symbol定义的对象属性不能使用for..in循环遍历,但是可以用Reflect.ownKeys来获取对象的所有键名
//创建Symbol,实现了唯一
let s1 = Symbol();
console.log(s);
let s2 = Symbol("尚硅谷"); //括号里面的只是描述
console.log(s2);
let s3 = Symbol("尚硅谷")
console.log(s2 === s3) //false;值是唯一的
//Symbol.for 创建
let s4 = Symbol.for("尚硅谷");
Sysbol的使用场景
//对象里添加唯一的属性
let youxi = {
name : '狼人杀',
[Symbol('say')]:function(){
console.log("我可以发一")
}
}
console.log("youxi",youxi);
迭代器 Iterator
原理:创建一个指针对象,指向当前数据结构的起始位置,第一次调用next方法,指针指向第一个成员,直至到最后一个成员,每次都会返回value和done属性的对象
const xiyou = ['唐僧','孙悟空','猪八戒','沙僧'];
let iterator = xiyou[Symbol.iterator]();
//调用对象的next方法
console.log(iterator.next());//{value:'唐僧',done:false}
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());//迭代完成,会返回{value:undefined,done:true}
==需要自定义遍历数据的时候,用迭代器==
生成器
生成器函数是ES6提供的一种异步编程解决方法,语法行为与传统函数完全不同
//异步编程,纯回调函数
function *gen(){
console.log("111");
yield '一只没有耳朵';
console.log("222");
yield '一只没有尾巴';
console.log("333");
yield '真奇怪';
console.log("HELLO GENERATOR")
}
let iterator = gen();
iterator.next();
// 111 {value:'一只没有耳朵',done:false}
iterator.next();//222
iterator.next();//333
iterator.next();//HELLO GENERATOR
//迭代器还可以遍历
for(let v of gen){
console.log(v);
}
//循环输出yield的值
生成器函数
function *gen(arg){
console.log("args",args);
let one = yield 111;
console.log(one);
yield 222;
}
//可以传参
let interator = gen("AAA");
interator.next();//AAA
//此时传入的参数会作为第一个yield返回的结果
interator.next('BBB'); //BBB
集合set
新的数据结构Set(集合),类似数组,但成员的值是唯一的,集合实现了interator接口,所以可以使用==扩展运算符==和[for...of]进行遍历
- size 返回集合的元素个数
- add 增加一个新元素,返回当前集合
- delete 删除元素,返回boolean值
- has 检测集合中是否包含某个元素,返回boolean值
- clear 清空
let s = new Set([1,2,3,4,5,2,3]); //会自动帮你去重
console.log(s,typeof(s));
//元素个数
s.size;
//添加新元素
s.add(7)
//删除元素
s.delete(4); //true
//检测是否包含元素
s.has(2) //true
//清空元素
s.clear();
let arr = [1,2,3,4,5,4,3,2,1]
//1.数组去重;
let result = [...new Set(arr)]
console.log(result);
//2.交集
let arr2 = [4,5,5,7];
let result = [...new Set(arr)].filter(item=>{
new Set(arr2).has(item)
})
//3.并集
let union = [...new Set([...arr,...arr2])];
console.log(union)
//4.差集
let diff = [...new Set(arr)].filter((item)=>!(new Set(arr2).has(item)))
Map
ES6提供了Map数据结构,类似于对象,也是键值对的集合,但是键的范围不限于字符串,各种类型的值都可以当做键。Map也实现了iterator接口,可遍历
//创建一个空map
let m = new Map();
//创建一个非空map
//添加元素
m.set('name','ronald'); // {name : ronald}
m.set('change',function(){
console.log("我们可以改变你");
})
let key = {
school: 'ATGUIGU'
};
m.set(key,['北京','上海','深圳']);
//size
console.log(m.size)
//删除
m.delete('name');
//获取
m.get('change');
//清空
m.clear()
//遍历
for(let v of m){
console.log(v)
}
class 类
是一个语法糖
class Phone{
//构造方法
constructor(brand,price){
this.brand = brand;
this.price = price;
}
call(){
console.log("我可以电话");
}
}
let HuaWei = new Phone("华为",1999);
HuaWei.call(); //我可以电话
静态成员,实例化出来的对象不可以拿到,只能class内部使用
class Phone{
static name = '手机'
//构造方法
constructor(brand,price){
this.brand = brand;
this.price = price;
}
call(){
console.log("我可以电话");
}
}
getter 和 setter 方法
class Phone1{
get price(){
console.log("获取到价格")
return '价格:1999'
}
set price(newVal){
console.log("价格被修改了");
}
}
let p1 = new Phone1()
console.log(p1.price) //获取到价格
s.price = 'free'; //价格被修改了
get方法更多用于计算属性,set方法更多用于改变值前进行校验用
数值的扩展
- Number.EPSILON 表示javascript里的最小精度
- Number.isFinite //检测数值是否为有限数
- Number.isNaN //检测数值是否为NAN
- Number.parseInt //字符串转整数
- Number.isInteger //判断是否为整数
- Math.sign //判断数到底为整数负数还是0
对象方法扩展
- Object.is //判断两个值是否完全相等
- Object.assign //对象的合并
- Object.setPropertyOf //设置原型对象
- Object.getPropertyOf //获取原型对象
ES7新特性
Array.prototype.includes
let array = [2,3,4,5,6]
console.log(array.includes(4)) //true
指数操作符
[**]可以实现幂运算,功能与Math.pow结果相同
2**10 //1024
ES8新特性
Async 和 await
- await必须写在async函数中
- await右侧的表达式一般为promise对象
- await返回的是promise成功的值
- await的promise失败了就抛出异常,需要通过try...catch捕获处理
Object.values、Object.keys 和Object.entries
const school = {
name : '尚硅谷',
cities : ['北京','上海','深圳'],
xueke:['前端','java','大数据','运维']
}
//获取所有的键
console.log(Object.keys(school)); //["name", "cities", "xueke"]
//获取所有的值
console.log(Object.value(school)); //["尚硅谷", ['北京','上海','深圳'], ['前端','java','大数据','运维']]
//获取所有值的数据
console.log(Object.entries(school)); //(3) [Array(2), Array(2), Array(2)]
////获取对象属性的描述对象
console.log(Object.getOwnPropertyDescriptors(school))
//cities: {value: Array(3), writable: true, enumerable: true, configurable: true}
//name: {value: "尚硅谷", writable: true, enumerable: true, configurable: true}
//xueke: {value: Array(4), writable: true, enumerable: true, configurable: true}
ES9的新特性
对象展开符
function connect({host,prot,...user}){
console.log(host);
console.log(port);
console.log(user); //{username:'ronald',pwd :'123'}
}
connect({
host : '127.0.0.1',
port : 3306,
username : 'ronald',
pwd : '123'
})
let a = {name:'ronald',age:18};
let b = {say(){console.log("123")}}
let c = {...a,...b};
console.log(c)
正则扩展-命名捕获分组
//声明一个字符串
let str = '<a href="http://www.atguigu.com">尚硅谷</a>'
//提取url与标签文本
const reg =/<a href="(?<url>.*)">(?<hostname>.*)<\/a>/;
//执行
const result = reg.exec(str);
ES10
对象的扩展方法Object.fromEntries
将数组转成对象
const nestedArray = [ ['key 1', 'value 1'],
['key 2', 'value 2']
]
Object.fromEntries(nestedArray);
// { key 1: "value 1", key 2: "value 2"}
trim、trimStarth和trimEnd 清除空格
const aa = ' 1234 ';
console.log(aa.trim())
console.log(aa.trimStart());
console.log(aa.trimEnd());
数组扩展-flat、flatMap
flat的参数为深度,就是可以展开多少层的意思
let arr = [1,2,3,4,[5,6,[7,8]]];
console.log(arr.flat(2)); //[1,2,3,4,5,67,8]
let arr1 = [1,2,3,[4,5]]
let result = arr1.flatMap(item = >[item *10])
console.log(result);
ES11
私有属性
class Person{
name;
#age;
#weight;
constructor(name,age,weight)}{
this.name = name;
this.#age = age;
this.#weight = weight;
}
intro(){
console.log(this.#age);
}
}
//实例化
const girl = new Person("xiaohong",18,'45kg')
console.log(girl.#age); //报错,private filed
console.log(girl.intro) //18 内部访问就不会报错
Promise.allSettled([]);
用于批量异步的场景,参数为数组,返回的结果始终的成功的promise对象,与Promise.all不同,Promise.all如果有一个失败就失败
const p1 = new Promise((resolve,reject)=>{
resolve('ok')
})
const p2 = new Promise((resolve,reject)=>{
resolve('ok1')
})
const result = Promise.allSettled([p1,p2]);
console.log(result);
String.prototype.matchAll
let str = `<ul>
<li>
<a>肖生克的救赎</a>
<p>上映日期:1994-09-10</p>
</li>
<li>
<a>阿甘正传</a>
<p>上映日期:1991-09-10</p>
</li>
</ul>`
const reg = /<li>.*?<a>(?<name>.*?)<\/a>.*?<p>(?<date>.*?)<\/p>/sg
//调用
const result = str.matchAll(reg); //迭代器,可用for of 或者展开符...
for(let v of result){
console.log(v);
}
const arr = [...result];
console.log(arr);
可选链操作符 ?.
?.会先判断前面的值是否存在,存在则进行下面的判断,如果不存在则返回undefined
let data = {
info : {
name : '123',
age : 22
}
}
const a = data.aa.name;
console.log(a) //报错
const name = data?.aa?.name;
console.log(name);//不报错
动态import
动态加载模块 type="module"
<script>
let btn = document.getElementById("btn");
btn.onclick = function () {
//动态import模块
import("./1.js").then((module) => {
console.log(module);
});
};
</script>
BigInt 类型
主要用于大数值运算
//第一种方法
let n = 521n; //在整数后面增加一个n代表大整形
console.log(n,typeof(n));
//第二种方法
console.log(BigInt(123))
globalThis 绝对全局变量
始终指向全局的window对象