ES6~ES11新特性 - 详解

一、ES

全称为ECMAScript。即为脚本语言的规范,一种脚本程序设计语言,而平时经常编写的JavaScript是ES的一种实现。
ECMA(European Computer Manufacturers Association)中文名称为欧洲计算机制 造商协会,这个组织的目标是评估、开发和认可电信和计算机标准。1994 年后该 组织改名为 Ecma 国际。

二、ES6的新特性

1.let 关键字

用来声明变量,使用let声明的变量有以下几个特点:

  1. 不允许重复声明
  2. 块级作用域(全局,函数,eval——再es5的严格模式下才能使用)
  3. 不存在变量类型提升
  4. 不影响作用域链
作用域的集合就是作用域链(子集可以访问父集,父集不能访问子集)
{
letschool='尚硅谷';
functionfn() {
// 2.函数内部输出 ,下面没有向上一级寻找变量
console.log(school);
}
// 1、调用函数 
fn()
}

2.const声明

特点:

  • 声明必须赋初始值
  • 标识符一般为大写
  • 不允许重复声明
  • 值不允许修改
  • 块级作用域
  • 对于数组和对象的元素进行修改,不算做对常量的修改。
    注意:声明对象类型的时候使用const,而声明非对象类型声明选择let

3.变量的解构赋值

概念:就是进行拆分,从数组和对象中提取值,对变量进行赋值

1.数组的解构赋值

const arr = ['张学友', '刘德华', '黎明', '郭富城'];
let [zhang, liu, li, guo] = arr;

2.对象的解构赋值

//对象的解构赋值
const lin = {
name: '林志颖',
tags: ['车手', '歌手', '小旋风', '演员']
};
let {name, tags} = lin;
//复杂解构
let wangfei = {
name: '王菲',
age: 18,
songs: ['红豆', '流年', '暧昧', '传奇'],
history: [
{name: '窦唯'},
{name: '李亚鹏'},
{name: '谢霆锋'}
]
};
let {songs: [one, two, three], history: [first, second, third]} =
wangfei

注意:频繁使用数组方法、数组元素,就可以使用解构赋值

3.模版字符串

引入新的声明字符串方式:``,(‘’;“”)
特点:

  1. 字符串可以进行换行
let str = `<ul>
<li>沈腾</li>
<li>玛丽</li>
<li>魏翔</li>
<li>艾伦</li>
</ul>`;
  1. 可以使用${XXX}形式进行输出变量,可以进行变量的拼接
// 变量拼接
let star = '王宁';
let result = `${star}在前几年离开了开心麻花`;

4.对象的简化方法

ES6允许直接在大括号中直接进行写入变量和函数,作为对象的属性和方法,这样的书写更加简洁。

let name = '尚硅谷';
let change = function () {
console.log('可以提高你的技能');
}
//属性和方法简写
const school = {
name,
change,
improve() {
console.log('我们可以提高你的技能')
}
}

5.箭头函数

特性:

  • this是静态的,this始终指向函数声明时所在的作用域下的this的值,也不可以使用 call,apply,bind方法改变this的指向。
  • 箭头函数在全局作用域下声明时,this指向windows
/**
* 1. 通用写法
*/
// 小括号里面是形参花括号里面是代码体
let fn = (arg1, arg2, arg3) => {
return arg1 + arg2 + arg3;
}

注意:

  • 如果形参只有一个,则小括号可以直接省略
  • 函数体如果只有一条语句,花括号和return可以直接省略,return的值就是该条语句的执行结果
  • 伪数组不能使用数组的方法
  • 箭头函数this是静态的
  • 箭头函数不能作为构造函数实例化对象
自定义函数
函数返回类型 函数名(参数,参数)
{
函数体;
}
构造函数   比较特殊的是构造寒暑期可以new()出一个新的函数,并在new的过程中初始化该函数
构造函数的特点:
命名首字母大写。
内部使用的this关键字,来指向即将要生成的实例对象。
可以使用New来生成实例对象。
new () 的过程中究竟发生了什么?
创建一个新的对象。
将关键字this指向这个新对象。
执行构造函数里面的代码,并将构造函数里的属性和方法赋给这个新的对象的this。
将this这个当前对象返回。
arguments
只在函数中存在(箭头函数除外)
arguments 是一个伪数组
是一个集合,存储了我们传入的所参数
arguments具有length,可以通过下标访问
注意:伪数组不能使用数组的方法

使用arguments存储之后可以通过下标进行访问,比较简单

案例:

<!-- 需求——2 从数组中返回偶数的元素 -->
  <script>
    const arr = [1.36, 9, 10, 100, 25];
    // 普通函数 
    const result = arr.filter(function (item) {
    return item % 2 === 0
    })
    console.log(result)
    // 使用箭头函数
    const result1 = arr.filter(item => item % 2 === 0)
    console.log(result1)
    </script>

6.默认值设置:

  • ES6允许给函数参数赋值初始值
  • 形参初始值 具有默认值的参数一般位置都要靠后(潜规则)
  • 当设置默认值的时候,如果没有对应的元素值就调用初始值
  • 可以与解构赋值结合使用

7.rest参数

用于获取函数的实参,用来替代arguments
arguments可以获取函数调用时的一下实参

ES5 获取实参的方式
function date(){
oconsole.log(arguments);
}
date('白芷''思慧','王一博');
// 上面的案例获取的是Object 对象
//ES6 rest参数 获取函数实参的方法   这里获取的数据是数组
function(...args){
console.log(args);  // 获取的结果是数组,可以使用数组的一些方法 filter some every map 
}
date('白芷''思慧','王一博');
~注意: rest 参数必须放到参数的最后~
eg: function fn(a,b,...args){}

8.spread扩展运算符

…运算符能将数组转化成逗号分隔的参数序列
注意:
rest 参数在声明的时候是放在了函数声明的形参的位置
扩展运算法 【…】 使用的时候是放在了函数调用的实参的位置

案例:

  1. 数组的合并
const a=['小米','大豆'];
const b=['学生','阿帆'];
const all=[...a, ...b];
console.log(all);   // (4) ['小米', '大豆', '学生', '阿帆']
  1. 数组的克隆
const one=['E','F','G'];
const two=[...one];  // ['E','F','G']
console.log(two)
  1. 伪数组转换成真数组
<body>
  <div></div>
    <div></div>
      <div></div>
        <script>
          const divs = document.querySelectorAll('div');
          console.log(divs);  // 这时获取的是一个对象
          const divArr = [...divs];
          console.log(divArr);   // 这时获取的是一个数组
          </script>
            </body>

9.symbol数据类型

引入的一种新的与那时数据类型,表示独一无二的值,是JS的第七种数据类型

1.特点:

  • Symbol 的值的唯一的,用来解决命名冲突的问题
  • Symbol 的值不能与其他的数据类型直接进行运算
  • Symbol定义的对象属性不能使用for In循环遍历,但是可以使用 Reflect.ownKeys 获取对象的所有键名
//创建 Symbol的方式
// ***********************创建symbol 的方式1: ***********************
let s = Symbol();
console.log(s, typeof s);
//添加标识的 Symbol
let s2 = Symbol('尚硅谷');
let s2_2 = Symbol('尚硅谷');
console.log(s2 === s2_2);   // 输出false
// ***********************使用 Symbol for 创建 ***********************
let s3 = Symbol.for('尚硅谷');
let s3_2 = Symbol.for('尚硅谷');
console.log(s3 === s3_2);   // 输出为true

使用场景:
给对象添加属性和方法,表示独一无二的值

2.给对象添加方法(方式一)

let game = {
name : 'ran'
}
let methods = {
up:Symbol()
down:Symbol()
}
game[methods.up]=function(){
console.log('aaa');
}
game[methods.down]=function(){
console.log('bbb');
}
console.log(game)    // name: 'ran',Symbol(),Symbol()

(方式二)

let youxi = {
name: '狼人杀'[Symbol('say')]:function(){
console.log('阿萨德')
}
}
console.log(youxi)    // name:'狼人杀',Symbol(say)

3.内置值

在这里插入图片描述

在这里插入图片描述

10、迭代器

遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作。

  • ES6 创造了一种新的遍历命令 for…of 循环,Iterator 接口主要供 for…of 消费

  • 原生具备 iterator 接口的数据(可用 for of 遍历):Array、 Arguments、 Set、Map、String、TypedArray、NodeList
    工作原理:

  1. 创建一个指针对象,指向当前的数据结构的起始位置
  2. 第一次调用对象的next()方法,指针自动指向数据结构的第一个成员
  3. 接下来不断地调用next()方法,指针一直往后移动,直到指向最后一个成员
    4.每调用一下next()方法返回一个包含value和done属性的对象

总结:需要自定义遍历数组的时候,要想到迭代器

//   声明一个对象
const banji = {
name: "终极一班",
stus: [
'xiaoming',
'xiaowang',
'xiaotian',
'knight'
],
//  2. 加上迭代器————迭代器返回的是一个对象————第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员 
[Symbol.iterator]() {
// 索引变量
let index = 0;
// 在外层声明变量进行保存
let _this = this;
return {
next: function () {
//根据下标决定返回的结果
if (index < _this.stus.length) {
// 每一次调用next方法,都返回的结果就是false,我们需要对返回结果进行处理
const result = { value: _this.stus[index], done: false };
// 让下标进行自增
index++;  // 不进行自增 永远为0
// 返回结果
return result;
} else {
return { value: undefined, done: true };
}
}
};
}
}
//1. 遍历这个对象
for (let v of banji) {
console.log(v);   //这里显示不能被迭代   
// 要求使用 for...of... 进行遍历 返回的是数组里面的对象
}

11.生成器

ES6提供的一种异步编程解决方案,语法行为与传统的函数完全不同

// 声明的时候需要加 * 号
//  yield 函数代的分隔符 3个分隔符产生4块
function * gen(arg){
console.log(arg);  // 参数传递
// 可以出现 yield 语句
yield '一只没有耳朵';
yield '一只没有尾巴';
return '真奇怪';
}
//  执行的时候需要借助【【 iterator 【迭代器】 是一个接口,为各种不同的数据结构提供统一的访问机制  】】
let iterator = gen('AAA');
console.log(iterator.next());   // 每调用一次执行第一段 并且对yield 语句后面的数据进行返回
console.log(iterator.next());   // 第二次调用的时候传入的实参将作为第一个yield 语句的整体返回结果
console.log(iterator.next())
注: next 方法在调用的时候是可以传入实参的  实参就是业务语句的返回结果

整体传参和next 方法传参,next里面传递的参数将作为上一个语句的返回结果

1.生成器函数的参数传递

// 整体传参
function * gen(arg){
console.log(arg);
}
let iterator = gen('AAA');
// 使用next() 进行参数的传递
iterator.next('AAA')    // 第二次调用的时候传入的实参将作为第一个yield 语句的整体返回结果

其中,整个JS都是单线程的,异步也是单线程(文件操作、网路操作【ajax,request】、数据库操作)
代码说明

  • *的位置没有限制
  • 生成器函数返回的结果是迭代器对象,调用迭代器对象的next方法可以得到yieldd语句后的值
  • yield相当于函数的暂停标记,也可以认为是函数的分隔符,每调用一次next(),执行一段代码
  • next()方法可以传递实参,作为yield语句的返回值

12.promise基本介绍和使用

Promise 是 ES6 引入的异步编程的新解决方案。语法上 Promise 是一个构造函数, 用来封装异步操作并可以获取其成功或失败的结果。

  • Promise 构造函数: Promise (excutor) {}

  • Promise.prototype.then 方法

  • Promise.prototype.catch 方法

1. I/O流简介

IO流:I的全称是Input,O的全称是Output。表示读取,流可以看做是程序传输数据的通道。

作用:解决程序请求资源,输出资源的问题。
异步编程主要是IO的代码

2. promise 解决回调函数地狱的问题

地狱不是只回调嵌套,而是嵌套之后,代码的可读性和调试性都降低了
请添加图片描述

3.Promise封装读取文件

// 1.首先:需要引入fs 模块
const fs=request('fs');
// 2.调用方法读取文件
fs.readFile('./resources/为学.md',(err.data)=>{
if(err)throw err;
console.log(data.toString());
});
// 3. 使用promise 进行封装
const p=new Promise(function(resolve,reject){
fs.readFile("./resources/为学.md",(err.data)=>{
// 判断如果失败 
if(err)reject(err);
// 如果成功 
resolve(data);
});
});
p.then(function(value){
console.log(value.toString());
},function(reason){
console.log("读取失败")
});

4.Promise封装AJAX

// 接口地址: https://api.apiopen.top/getJoke
const p = new Promise((resolve, reject) => {
//1. 创建对象
const xhr = new XMLHttpRequest();
//2.初始化
xhr.open("GET", "https://api.apiopen.top/getJoke");
//3.发送
xhr.send();
//4. 绑定事件,处理响应结果
xhr.onreadystatechange = function () {
//判断 
if (xhr.readyState === 4) {
//判断响应状态码200-299
if (xhr.status >= 200 && xhr.status < 300) {
//表示成功
resolve(xhr.response)
} else {
//如果失败
reject(xhr.status);
}
}
}
})
//指定回调
p.then(function (value) {
console.log(value);
}, function (reason) {
console.error(reason);
});

5.Promise——then 方法

then()方法用来指定回调

then 方法返回结果的状态
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('用户数据');
//reject('出错啦');
}, 1000)
})
//调用then 【方法then方法的退回结果是Promise 对象,对象状态由回调函数的执行结果决定】
//1.如果回调函数中返回的结果是非promise 类型的属性,状态为成功,返回值为对象的成功的值
const result = p.then(value => {
console.log(value);
//1.非promise 类型的属性
//return 123;
//2.是promise 对象
// return new Promise((resolve, reject) => {
//     //resolve('ok');
//     reject('error')
/ });
//3.抛出错Error
throw new Error('出错啦!')
}, reason => {
console.warn(reason);
});
console.log(result);
//也可以链式调用,嵌套异步任务,杜绝回调域

6.Promise实践——读取多个文件

//引入fs模块
const fs = require("fs");
// 1. 读取多个文件的实现方法1:
//   fs.readFile('./hist.txt', (err, data1)=>{})    fs.readFile('文件路径', 回调函数)  回调地狱的问题:容易重名 重名之后不容易被发现,调试问题不方便
// fs.readFile('./hist.txt', (err, data1) => {
//     fs.readFile('./wx.txt', (err, data2) => {
//         fs.readFile('./sg.txt', (err, data3) => {
//             let result = data1 + '\r\n' + data2 + '\r\n' + data3 + '\n';
//             console.log(result);
//         });
//     });
// });
//读取多个文件的实现方法2: 使用promise 实现,不会产生回调地狱的现象
const p = new Promise((resolve, reject) => {
fs.readFile("./hist.txt", (err, data) => {
resolve(data);
});
});
p.then(value => {
// 这里不能在   fs.readFile("./wx.txt", (err, data) => {
//      resolve([value, data]);
// }); 里面继续嵌套,不然会出现回调地狱的问题,所以需要return 
return new Promise((resolve, reject) => {   // 这里为什么药返回Promise  因为 不return promise 是返回undefined  只有返回promise 才能接着调用 then 实现链式调用 
fs.readFile("./wx.txt", (err, data) => {
resolve([value, data]);   // resolve 可以改变peomise 对象的状态的
});
})
}).then(value => {
return new Promise((resolve, reject) => {
fs.readFile("./sg.txt", (err, data) => {
//压入
value.push(data);
resolve(value);
});
})
}).then(value => {
// join() 方法内部做了字符串的拼接
console.log(value.join('\r\n'));
})

补充:
buffer:Node.js提供的一种二进制缓冲区,常用来处理I/O操作

7.Promise——catch方法

const p = new Promise((resolve, reject) => {
setTimeout(() => {
//设置p对象的状态为失败,并设置失败的值
reject("出错啦!");
}, 1000)
});
// p.then(function (value) {}, function (reason) {
//     console.error(reason);
// });
// catch 可以理解为直接捕获错误  相当于then 填写失败回调
p.catch(function(reason){
console.warn(reason);
})

13.Set(集合)

集合介绍ES6提供了新的数据结构Set(集合)。它类似于数组,但成员的值都是唯一的。
集合实现了:

  • iterator 接口【为各种不同的数据结构提供统一的访问机制】
  • 可以使用【扩展运算符 ——(…)】
  • 以及【for…of…】进行遍历
    1. 集合的属性和方法:
    1) size: 返回集合的元素个数
    2)add: 增加一个新元素,返回当前集合
    3)delete: 删除元素,返回boolean 值
    4)has : 检测集合中是否包含某个元素,返回boolean值
    2.集合的实践
let arr1 = [1, 2, 3, 4, 5, 4, 3, 2, 1];
//1. 数组去重
let result1 = [...new Set(arr1)];
console.log(result1);
//2. 交集
let arr2 = [4, 5, 6, 5, 6];
// let result2 = [...new Set(arr1)].filter(item => {   【let result2=new Set(arr);  这个时候数组是一个集合 可以使用扩展运算符将集合变为一个数组 】
//     let s2 = new Set(arr2); // 4 5 6
//     if (s2.has(item)) {
//         return true;
//     } else {
//         return false;
//     }
// });
//简化
let result2 = [...new Set(arr1)].filter(item => new Set(arr2).has(item));
console.log(result2);
//3. 并集
let union = [...new Set([...arr1, ...arr2])];
console.log(union);
//4. 差集   差集中谁是主体结果是不一样的
let diff = [...new Set(arr1)].filter(item => !(new Set(arr2).has(item)));
console.log(diff);

补充:

它用于把一个数组转换为用逗号隔开的参数序列

14.Map

ES6提供了Map数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
Map也实现了iterator 接口,所以可以使用【扩展运算符】和【for…of…】进行遍历。

Map的属性和方法:

  • 1)size:返回Map的元素个数
  • 2)set:增加一个新元素,返回当前Map
  • 3)get:返回键名对象的键值
  • 4)has:检测Map中是否包含某个元素,返回boolean值
  • 5)clear:清空集合,返回undefined
//声明 Map
let m = new Map();
//添加元素
m.set('name', '尚硅谷');
console.log(m);
m.set('change', function () {
console.log("我们可以改变你!!");
});
console.log(m);
let key = {
school: 'ATGUIGU'
};
m.set(key, ['北京', '上海', '深圳']);
console.log(m);
//元素个数
console.log(m.size);
//删除
m.delete('name');
console.log(m);
//获取
console.log(m.get('change'));
console.log(m.get(key));
//遍历
for (let v of m) {
console.log(v);
}
//清空
m.clear();
console.log(m);

15.class类

ES6提供了更接近传统语言【java, c++】的写法,引入了Class (类)这个概念,作为对象的模板。
通过class关键字,可以定义类。基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而己。

知识点:

  • class声明类.
  • constructor定义构造函数的初始化
  • extends继承父类
  • super调用父级构造方法
  • static 定义静态方法和属性
  • 父类方法可以重写
//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);
//es6(class类)
class Shouji {
//构造方法名字不能修改
constructor(brand, price) {
this.brand = brand;
this.price = price;
}
//方法必须使用该语法,不能使用ES5 的对象完整形式
call() {
console.log("我也可以打电话!!");
}
}
let onePlus = new Shouji("1+", 1999);
onePlus.call();
console.log(onePlus);

补充:

什么是语法糖:指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会
显示原型 :prototype

class类中的静态成员

function Phone(){}   // 这是一个构造函数 构造函数本身也是一个对象 可以往对象上面添加属性和方法
Phone.name=手机;
Phone.change=function(){
console.log("晚上好!")
}: 实例对象和函数对象的实例是不通的
function Phone() {
}
Phone.name = '手机';
Phone.change = function () { //属于函数对象(静态成员,只有函数可以用)
console.log("我可以改变世界");
}
Phone.prototype.size = '5.5inch'; //属于实例对象
let nokia = new Phone(); //实例对象和函数对象不相通        
console.log(nokia.name); //undefined
// nokia.change();
console.log(nokia.size); //5.5inch
class Phone2 {
//静态属性
static name = '手机'; //属于类的对象(静态成员,只有类可以用),不属于实例对象
static change() {
console.log("我可以改变世界");
}
}
let nokia2 = new Phone2();
console.log(nokia2.name); //undefined
console.log(Phone2.name); //手机

静态属性和实例属性的区别

1、静态属性是类自身的属性,只能在类自身调用,而实例属性是实例对象的属性;
2、实例对象无法调用静态属性,但类可调用实例属性;
3、静态属性只有一种声明方法,语法“类名.属性名=值”,而实例属性有多种声明方法,例类中用“属性名=值”定义。
实例: 在 面向对象程序设计中,“类”在实例化之后叫做一个“实例”。 “类”是静态的,不占进程内存,而“实例”拥有动态内存。

16.ES5构造函数的继承

使用构造函数来实现继承
//手机(父类)
function Phone(brand, price) {
this.brand = brand;
this.price = price;
}
Phone.prototype.call = function () {
console.log("我可以打电话");
}
//智能手机(子类)
function SmartPhone(brand, price, color, size) {
Phone.call(this, brand, price);
this.color = color;
this.size = size;
}
//设置子级构造函数的原型
SmartPhone.prototype = new Phone;
//SmartPhone.prototype.constructor = SmartPhone; //可加可不加
//声明子类的方法
SmartPhone.prototype.photo = function () {
console.log("我可以拍照");
}
SmartPhone.prototype.playGame = function () {
console.log("我可以玩游戏");
}
const chuiz = new SmartPhone('锤子', 2499, '黑色', '5.5inch');
console.log(chuiz);
console.log(chuiz.price);
chuiz.call();
chuiz.photo();
chuiz.playGame();

17.class类的继承 与 子类对父类方法的重写

1.构造方法:

它没有返回值,即使是void型的值也不能够返回。它的任务就是为了对象初始化内部的状态。

2.构造方法

在创建对象时被系统调用(即自动调用,不需要程序员主动调用)

3.构造函数

当程序中包含有带参的构造函数的时候,系统将不再提供无参构造函数
[public]构造方法名([形参列表])
{
//方法体
}

两种构造方法

1. 不带参数的构造方法
eg:定义一个circle类
javascript
public class SameCircle
{
public SameCircle1() //无参数的构造方法
{
}
}
2有参数的构造方法
举例:同样定义一个圆
ublic class SameCircle
{
public SameCircle2( int noX, int noY, int nRa) //参数的构造方法,定义了圆心,半径
{
}
}
************************************
构造方法通过new调用 例如 创建对象时
Student stu = new Student(); new 后面跟构造方法名完全一样
******************************************************************
//总结:
//(1)构造方法的名字和类的名字要相同,大小写字母也要一样。
//(2)构造方法不能有返回值类型。
//(3)在构造方法体中也不能用return返回一个值。
//(4)主要作用是用于对象的初始化
//(5)在创建对象时系统自动调用,不能再代码中显示的调用
//(6)一个类中可以定义多个构造方法(参数序列要有明显的区别,这样才好区分具体用哪个)
//(7)类中不定义构造方法时,系统会自动为该类生成一个没有参数的构造方法。

18.class 中的getter和setter设置

// get和set
class Phone {
//对对象的动态属性进行封装
get price() {
console.log("价格属性被读取了");
return 'i love you';
}
//可对设置的值进行判断
set price(newVal) {
console.log('价格属性被修改了');
}
}
//实例化对象
let s = new Phone();
console.log(s.price);
console.log("\n");
s.price = 'free';

19.数值扩展

1、Number. EPSILON

是JavaScript 表示的最小精度,EPSILON 属性的值接近于2. 2204460492503130808472633361816E-16 【2.22*10负16次方】

function equal(a, b) {
if (Math.abs(a - b) < Number.EPSILON) {
return true;
} else {
return false;
}
}
console.log(0.1 + 0.2 === 0.3);
console.log(equal(0.1 + 0.2, 0.3))

2、二进制和八进制

let b = 0b1010; //二进制
console.log(b);
let o = 0o777; //八进制
console.log(o);
let d = 100; //十进制
console.log(d);
let x = 0xff; //十六进制
console.log(x);

3、 Number.isFinite 检测一个数值是否为有限数

console.log(Number.isFinite(100));
console.log(Number.isFinite(100 / 0));
console.log(Number.isFinite(Infinity)); //无穷

4.Number.isNaN检测一个数值是否为NaN

console.log(Number.isNaN(123));

5、Number.parseInt、Number . parseFloat字符串转整数

console.log(Number.parseInt('5211314love'));
console.log(Number.parseFloat('3.1415926神奇'));

6、 Number.isInteger判断一个 数是否为整数

console.log(Number.isInteger(5));
console.log(Number.isInteger(2.5));

7、Math.trunc 将数字的小数 部分抹掉

console.log(Math.trunc(3.5));

8、 Math.sign 判断一个数到底为正数、负数还是零

console.log(Math.sign(100));
console.log(Math.sign(0));
console.log(Math.sign(-20000));

20. ES6 对象方法扩展

1、Object.is 判断两个值是否完全相等

console.log(Object.is(120, 120)); //ture
console.log(Object.is(120, 121)); //flase
console.log(Object.is(NaN, NaN)); //ture
console.log(NaN === NaN); //flase,所以Object.is和===不一样  两个NaN 进行比较除了不等于都是false 

2、Object.assign 对象的合并

//用于配置合并
const config1 = {
host: 'localhost ',
port: 3306,
name: 'root',
pass: 'root',
test: 'test'
};
const config2 = {
host: 'http://atguigu.com',
port: 33060,
name: 'baidu.com',
pass: 'iloveyou',
//test2: 'test2' //有则覆盖,无则不覆盖
}
console.log(Object.assign(config1, config2)); //2覆盖1

3、Object. setPrototype0f(设置原型对象)、Object.getPrototypeof(获取原型对象)

const school = {
name: '尚硅谷'
}
const cities = {
xiaoqu: ['北京', ' 上海', '深圳']
}
Object.setPrototypeOf(school, cities); //将cities设置为school的原型对象,但最好不用此方法设置
console.log(school);
console.log(Object.getPrototypeOf(school)); //获取school的原型对象

21.模块化

模块化是指将一个大的程序文件,拆分成许多小的文件(模块),然后将小文件组合起来。

优势与规范化产品

1、模块化的优势有以下几点:
  • 1)防止命名冲突
  • 2)代码复用
  • 3)高维护性
2、ES6之前的模块化规范有:
  • 1)CommonJS => NodeJS、Browserify
  • 2)AMD => requireJS3)CMD => seaJS

浏览器使用ES6模块化引入模块

ES6 模块化语法
模块功能主要由两个命令构成:export 和import。

  1. export命令用于规定模块的对外接口
  2. import命令用于输入其他模块提供的功能
//import 导入模块变量-----这里在导入的时候变量需要重命名,import的时候必须使用大括号!
//按需引入math模块各个变量
import{del,add,sub as subList}from"@/api/math.js"
console.log(de1)
console.log(add(24))
console.log(subList(203))
//一次性全部导入模块变量!用*
//全部引入math.js模块变量
import*as math from"@/api/math.js"  // *——代表所有  math——自定义的重命名
console.1og(math.de1)
console.1og(math.add(24))
console.Log(math.subList(203)

22. ES6模块暴露数据语法汇总

//分别暴露
在每个需要暴露的数据的前面加 export
//统一暴露
let school = '尚硅谷';
function find() {
console.log("我们可以帮助你找工作");
}
export{school,find};
//默认暴露
export default {
school: 'ATGUIGU',
change: function () {  //m3.default.change();
console.log("我们可以改变你!!");
}
}

23. ES6模块引入模块数据语法汇总

//1.通用导入方式
import*as math from"@/api/math.js"  // *——代表所有  math——自定义的重命名
//2. 解构赋值形式
//import {school, teach} from"./m1.js";
//import {school as guigu, find} from "./m2.js";
// 默认暴露的形式
//import {default as m3} from "./m3.js";
//3. 简便形式,只针对默认暴露
import m3 from "./m3.js";
console.log(m3);

浏览器使用ES6模块化方式二

//html文件里面的script标签
<script src="./app.js" type="module"></script>         // 注意类型需要设置为module 

24. Babel 对ES6模块化代码转化

Babel 是一个javaScript编译器,可以将es6比较新的语法转化为浏览器可以识别的语法

需要安装的工具
babel-cil   babel-preset-env   browserify (browserify进行打包比较简单)  在项目中一般使用webpack 进行打包
npm init --yes 进行初识化
-D 开发依赖
1.安装工具babel-cil   babel-preset-env   browserify -D 表示开发依赖
2.之后需要使用 npx babel src/js -d dist/js  进行转换
3. 打包 npx browserify dist/js/app.js -o  (-o 表示输出 表示最终把文件输出到那个位置)

25. ES6模块化引入NPM包

npm i jquery
// 修改背景颜色为粉色
import $ from 'jquery';   es6 导入npm 包的语法   // 相当于 const $ =require("jquery");
$('body').css('background','pink');

三、ES7新特性

1.Array.prototype.includes Includes

方法用来检测数组中是否包含某个元素,返回布尔类型值

2.指数操作符

在 ES7 中引入指数运算符「**」,用来实现幂运算,功能与 Math.pow 结果相同

Math.pow(2,10);  // 1024  相当于2的10次方

四、ES8 新特性

1.async 和 await

async 和 await 两种语法结合可以让异步代码像同步代码一样

1.async 函数

async 函数的返回值为 promise 对象, // promise 对象代表未来将要发生的事件,用来传递异步操作的消息

promise 对象的结果由 async 函数执行的返回值决定

2.await 表达式

  • await 必须写在 async 函数中

  • await 右侧的表达式一般为 promise 对象

  • await 返回的是 promise 成功的值

  • await 的 promise 失败了, 就会抛出异常, 需要通过 try…catch 捕获处.await 表达式

2 Object.values 和 Object.entries

  • Object.values()方法返回一个给定对象的所有可枚举属性值的数组

  • Object.entries()方法返回一个给定对象自身可遍历属性 [key,value] 的数组

3.Object.getOwnPropertyDescriptors

该方法返回指定对象所有自身属性的描述对象

console.log(Object.getOwnPropertyDescriptors(school));

五、ES9新特性

1.Rest/Spread 属性

Rest 参数与 spread 扩展运算符在 ES6 中已经引入,不过 ES6 中只针对于数组,在 ES9 中为对象提供了像数组一样的 rest 参数和扩展运算符

function connect({host, port, ...user}) { // host 和port 还是存储到变量里面,其余其他属性键或值存储到user 里面
console.log(host);                          // 如果有更多的参数,参数也会存储到user当中去  【user 只是随意的命名】
console.log(port);
console.log(user);
}
connect({
host: '127.0.0.1',
port: 3306,
username: 'root',
password: 'root',
type: 'master'
});

2.正则表达式命名捕获组

ES9 允许命名捕获组使用符号『?』,这样获取捕获结果可读性更强

let str = '<a href="http://www.atguigu.com">尚硅谷</a>';
const reg = /<a href="(?<url>.*)">(?<text>.*)<\/a>/;
  const result = reg.exec(str);
  console.log(result.groups.url);
  console.log(result.groups.text);

eg:进行对象的合并

正则扩展——命名捕获分组
对分组匹配的结果进行命名方便对结果进行处理 【对捕获结果添加属性,方便我们进行提取】

通过正则 对字符串的部分信息进行捕获提取

3.正则表达式反向断言

ES9 支持反向断言,通过对匹配结果前面的内容进行判断,对匹配进行筛选。 【对匹配结果进行判断】

//声明字符串
let str = 'JS5211314 你知道么 555 啦啦啦';
//正向断言
const reg = /\d+(?=啦)/;
const result = reg.exec(str);   // 555  根据啦的内容判断前面的内容
//反向断言
const reg = /(?<=么)\d+/;
const result = reg.exec(str)   // 根据么判断后面的 5 
根据目标内容的前面和后面对它做唯一性的识别

4 ES9 正则扩展——dotALL 模式

正则表达式中点.匹配除回车外的任何单字符,标记『s』改变这种行为,允许行终止符出现\

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>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/gs;
//执行匹配
const result = reg.exec(str);
let result;
let data = [];
while(result = reg.exec(str)){
data.push({title: result[1], time: result[2]});
}
//输出结果
console.log(data)

六、ES10新特性

1.Object.fromEntries

用来创建对象,接收二维数组或者Map

map 是一种数据结构,其实也是一种对象

2.trimStart 和 trimEnd

字符串的扩展方法:

  • trim 清除字符创两侧的空白字符
  • trimStart trimEnd 用来指定清除左侧还是右侧的空白字符

3.Array.prototype.flat 与 flatMap

flat : 平 将多维数组转换为低维数组

二维转一维
请添加图片描述

三维转一维

请添加图片描述

6.4.Symbol.prototype.description

用来获取 Symbol 的字符串描述

七、ES 11 新特性

1.类的私有属性

对属性的一个封装,不让外部对他们做直接的操作

通过构造方法来进行初始化 私有属性声明的时候需要用到 #

2.Promise.allSettled

Promise.all()    全部成功之后才可以返回一个成功的结果           想要最终的成功的结果的时候使用
Promise.allSettled()   始终可以返回一个成功,始终能够得到每一个promise 成功和失败的状态以及结果  想要得到每一个的结果的时候使用

3.String.prototype.matchAll

字符串扩展 matchAll 方法用来得到正则批量匹配的结果

请添加图片描述

返回的是一个可迭代对象

请添加图片描述

也可以用扩展运算符将它展开
请添加图片描述

4.可选链操作符

当我们面对对象类型的参数的时候

允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。操作符的功能类似于 .
链式操作符,不同之处在于,在引用为空(nullish ) (null 或者 undefined) 的情况下不会引起错误,该表达式短路返回值是
undefined。与函数调用一起使用时,如果给定的函数不存在,则返回 undefined。

5.动态 import 导入

ES6 模块化是一个静态的模块系统 在写import的时候一般是在app.js 入口文件中写入之后进行导入工作的 动态import
可以实现按需要加载

原来的导入是一口气将所有将会用到的外部文件import

ES11 支持import函数 返回的是Promise对象 在要使用到外部文件的时候在引入 实现了懒加载

Promise成功的值就是导入的对象

请添加图片描述

6 BigInt类型 【大整数型】

在普通整型数据的基础上面加 n 就可以啦

应用于大数值的运算

请添加图片描述

请添加图片描述

请添加图片描述

BigInt 类型不能直接和普通int 类型进行运算

7.globalThis 对象

javascript 含义:全局的this 无论执行环境是什么,始终指向全局对象
对全局对象进行操作可以使用,这样子可以忽略环境直接使用

对比总计表

版本发布年份核心特性改进方向典型应用场景
ES52009“use strict”、JSON 支持、数组迭代方法(forEach/map)、Object.defineProperty基础功能完善兼容性代码、传统项目维护
ES62015let/const、箭头函数、类、模板字符串、解构、模块化、Promise、Symbol现代化语法革命现代前端框架(React/Vue)开发基础
ES72016Array.includes()、指数运算符(**)工具方法补充数组操作、数学计算
ES82017async/await、Object.values()/entries()、字符串填充(padStart)异步流程控制异步请求处理、对象数据转换
ES92018for-await-of、对象 Rest/Spread、正则命名捕获组异步迭代与对象操作流式数据处理、复杂正则匹配
ES102019Array.flat()/flatMap()、Object.fromEntries()、可选 catch 参数数据操作简化嵌套数据扁平化、错误处理简化
ES112020Promise.allSettled()、可选链(?.)、空值合并(??)、BigInt安全访问与大数据支持防御性编程、大整数运算
ES122021逻辑赋值运算符(=/&&=)、String.replaceAll()、WeakRef语法糖与内存管理、代码简化、缓存优化
ES132022类私有字段/方法、Array.at()、顶层 await、Error.cause封装性与工程化模块化开发、错误链式追踪
ES142023Array.findLast()、toReversed()、Object.groupBy()、Hashbang 标准化不可变操作与数据分组数据聚合分析、不可变数据场景

主要演进路线

关键演进路线

  1. 从 ES5 到 ES6
  • 跨越式升级:从基础功能到现代化语法(如箭头函数、类、模块化)。

  • 影响:奠定现代 JavaScript 开发基础,推动前端工程化。

  1. ES7-ES10
  • 渐进增强:填补工具方法(如数组/对象操作)、优化异步编程(async/await)。

  • 目标:提升开发效率和代码可读性。

  1. ES11-ES14
  • 精细化改进:安全访问(可选链)、内存管理(WeakRef)、不可变数据操作。

  • 趋势:面向大型应用开发与性能优化。

posted @ 2025-11-16 17:01  gccbuaa  阅读(51)  评论(0)    收藏  举报