一、ES
全称为ECMAScript。即为脚本语言的规范,一种脚本程序设计语言,而平时经常编写的JavaScript是ES的一种实现。
ECMA(European Computer Manufacturers Association)中文名称为欧洲计算机制 造商协会,这个组织的目标是评估、开发和认可电信和计算机标准。1994 年后该 组织改名为 Ecma 国际。
二、ES6的新特性
1.let 关键字
用来声明变量,使用let声明的变量有以下几个特点:
- 不允许重复声明
- 块级作用域(全局,函数,eval------再es5的严格模式下才能使用)
- 不存在变量类型提升
- 不影响作用域链
javascript
作用域的集合就是作用域链(子集可以访问父集,父集不能访问子集)
{
letschool='尚硅谷';
functionfn() {
// 2.函数内部输出 ,下面没有向上一级寻找变量
console.log(school);
}
// 1、调用函数
fn()
}
2.const声明
特点:
- 声明必须赋初始值
- 标识符一般为大写
- 不允许重复声明
- 值不允许修改
- 块级作用域
- 对于数组和对象的元素进行修改,不算做对常量的修改。
注意:声明对象类型的时候使用const,而声明非对象类型声明选择let
3.变量的解构赋值
概念:就是进行拆分,从数组和对象中提取值,对变量进行赋值
1.数组的解构赋值
javascript
const arr = ['张学友', '刘德华', '黎明', '郭富城'];
let [zhang, liu, li, guo] = arr;
2.对象的解构赋值
javascript
//对象的解构赋值
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.模版字符串
引入新的声明字符串方式:``,('';"")
特点:
- 字符串可以进行换行
javascript
let str = `<ul>
<li>沈腾</li>
<li>玛丽</li>
<li>魏翔</li>
<li>艾伦</li>
</ul>`;
- 可以使用${XXX}形式进行输出变量,可以进行变量的拼接
javascript
// 变量拼接
let star = '王宁';
let result = `${star}在前几年离开了开心麻花`;
4.对象的简化方法
ES6允许直接在大括号中直接进行写入变量和函数,作为对象的属性和方法,这样的书写更加简洁。
javascript
let name = '尚硅谷';
let change = function () {
console.log('可以提高你的技能');
}
//属性和方法简写
const school = {
name,
change,
improve() {
console.log('我们可以提高你的技能')
}
}
5.箭头函数
特性:
- this是静态的,this始终指向函数声明时所在的作用域下的this的值,也不可以使用 call,apply,bind方法改变this的指向。
- 箭头函数在全局作用域下声明时,this指向windows
javascript
/**
* 1. 通用写法
*/
// 小括号里面是形参花括号里面是代码体
let fn = (arg1, arg2, arg3) => {
return arg1 + arg2 + arg3;
}
注意:
- 如果形参只有一个,则小括号可以直接省略
- 函数体如果只有一条语句,花括号和return可以直接省略,return的值就是该条语句的执行结果
- 伪数组不能使用数组的方法
- 箭头函数this是静态的
- 箭头函数不能作为构造函数实例化对象
javascript
自定义函数
函数返回类型 函数名(参数,参数)
{
函数体;
}
构造函数 比较特殊的是构造寒暑期可以new()出一个新的函数,并在new的过程中初始化该函数
构造函数的特点:
命名首字母大写。
内部使用的this关键字,来指向即将要生成的实例对象。
可以使用New来生成实例对象。
new () 的过程中究竟发生了什么?
创建一个新的对象。
将关键字this指向这个新对象。
执行构造函数里面的代码,并将构造函数里的属性和方法赋给这个新的对象的this。
将this这个当前对象返回。
javascript
arguments
只在函数中存在(箭头函数除外)
arguments 是一个伪数组
是一个集合,存储了我们传入的所参数
arguments具有length,可以通过下标访问
注意:伪数组不能使用数组的方法
使用arguments存储之后可以通过下标进行访问,比较简单
案例:
javascript
<!-- 需求------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可以获取函数调用时的一下实参
javascript
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 参数在声明的时候是放在了函数声明的形参的位置
扩展运算法 【...】 使用的时候是放在了函数调用的实参的位置
案例:
- 数组的合并
javascript
const a=['小米','大豆'];
const b=['学生','阿帆'];
const all=[...a, ...b];
console.log(all); // (4) ['小米', '大豆', '学生', '阿帆']
- 数组的克隆
javascript
const one=['E','F','G'];
const two=[...one]; // ['E','F','G']
console.log(two)
- 伪数组转换成真数组
javascript
<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 获取对象的所有键名
javascript
//创建 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.给对象添加方法(方式一)
javascript
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()
(方式二)
javascript
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
工作原理:
- 创建一个指针对象,指向当前的数据结构的起始位置
- 第一次调用对象的next()方法,指针自动指向数据结构的第一个成员
- 接下来不断地调用next()方法,指针一直往后移动,直到指向最后一个成员
4.每调用一下next()方法返回一个包含value和done属性的对象
总结:需要自定义遍历数组的时候,要想到迭代器
javascript
// 声明一个对象
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提供的一种异步编程解决方案,语法行为与传统的函数完全不同
javascript
// 声明的时候需要加 * 号
// 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.生成器函数的参数传递
javascript
// 整体传参
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封装读取文件
javascript
// 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
javascript
// 接口地址: 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()方法用来指定回调
javascript
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实践------读取多个文件
javascript
//引入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方法
javascript
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.集合的实践
javascript
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
javascript
//声明 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 定义静态方法和属性
- 父类方法可以重写
javascript
//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类中的静态成员
javascript
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); //手机
静态属性和实例属性的区别
javascript
1、静态属性是类自身的属性,只能在类自身调用,而实例属性是实例对象的属性;
2、实例对象无法调用静态属性,但类可调用实例属性;
3、静态属性只有一种声明方法,语法"类名.属性名=值",而实例属性有多种声明方法,例类中用"属性名=值"定义。
实例: 在 面向对象程序设计中,"类"在实例化之后叫做一个"实例"。 "类"是静态的,不占进程内存,而"实例"拥有动态内存。
16.ES5构造函数的继承
javascript
使用构造函数来实现继承
//手机(父类)
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\]构造方法名(\[形参列表\])
{
//方法体
}
#### 两种构造方法
```javascript
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设置
```javascript
// 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次方】
```javascript
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、二进制和八进制
```javascript
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 检测一个数值是否为有限数
```javascript
console.log(Number.isFinite(100));
console.log(Number.isFinite(100 / 0));
console.log(Number.isFinite(Infinity)); //无穷
```
#### 4.Number.isNaN检测一个数值是否为NaN
```javascript
console.log(Number.isNaN(123));
```
#### 5、Number.parseInt、Number . parseFloat字符串转整数
```javascript
console.log(Number.parseInt('5211314love'));
console.log(Number.parseFloat('3.1415926神奇'));
```
#### 6、 Number.isInteger判断一个 数是否为整数
```javascript
console.log(Number.isInteger(5));
console.log(Number.isInteger(2.5));
```
#### 7、Math.trunc 将数字的小数 部分抹掉
```javascript
console.log(Math.trunc(3.5));
```
#### 8、 Math.sign 判断一个数到底为正数、负数还是零
```javascript
console.log(Math.sign(100));
console.log(Math.sign(0));
console.log(Math.sign(-20000));
```
### 20. ES6 对象方法扩展
#### 1、Object.is 判断两个值是否完全相等
```javascript
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 对象的合并
```javascript
//用于配置合并
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(获取原型对象)
```javascript
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命令用于输入其他模块提供的功能
```javascript
//import 导入模块变量-----这里在导入的时候变量需要重命名,import的时候必须使用大括号!
//按需引入math模块各个变量
import{del,add,sub as subList}from"@/api/math.js"
console.log(de1)
console.log(add(2,4))
console.log(subList(20,3))
//一次性全部导入模块变量!用*
//全部引入math.js模块变量
import*as math from"@/api/math.js" // *------代表所有 math------自定义的重命名
console.1og(math.de1)
console.1og(math.add(2,4))
console.Log(math.subList(20,3)
```
### 22. ES6模块暴露数据语法汇总
```javascript
//分别暴露
在每个需要暴露的数据的前面加 export
//统一暴露
let school = '尚硅谷';
function find() {
console.log("我们可以帮助你找工作");
}
export{school,find};
//默认暴露
export default {
school: 'ATGUIGU',
change: function () { //m3.default.change();
console.log("我们可以改变你!!");
}
}
```
### 23. ES6模块引入模块数据语法汇总
```javascript
//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模块化方式二**
```javascript
//html文件里面的script标签
// 注意类型需要设置为module
```
### 24. Babel 对ES6模块化代码转化
Babel 是一个javaScript编译器,可以将es6比较新的语法转化为浏览器可以识别的语法
```javascript
需要安装的工具
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包
```javascript
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 结果相同
```javascript
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
该方法返回指定对象所有自身属性的描述对象
```javascript
console.log(Object.getOwnPropertyDescriptors(school));
```
## 五、ES9新特性
### 1.Rest/Spread 属性
Rest 参数与 spread 扩展运算符在 ES6 中已经引入,不过 ES6 中只针对于数组,在 ES9 中为对象提供了像数组一样的 rest 参数和扩展运算符
```javascript
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 允许命名捕获组使用符号『?』,这样获取捕获结果可读性更强
```javascript
let str = '尚硅谷';
const reg = /(? (.*?)<\/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
```javascript
用来获取 Symbol 的字符串描述
```
## 七、ES 11 新特性
### 1.类的私有属性
对属性的一个封装,不让外部对他们做直接的操作
通过构造方法来进行初始化 私有属性声明的时候需要用到 #
### 2.Promise.allSettled
```javascript
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 无论执行环境是什么,始终指向全局对象
>
> 对全局对象进行操作可以使用,这样子可以忽略环境直接使用
## 对比总计表
| 版本 | 发布年份 | 核心特性 | 改进方向 | 典型应用场景 |
|------|------|----------------------------------------------------------------|--------------------|-----------------------|
| ES5 | 2009 | "use strict"、JSON 支持、数组迭代方法(forEach/map)、Object.defineProperty | 基础功能完善 | 兼容性代码、传统项目维护 |
| ES6 | 2015 | let/const、箭头函数、类、模板字符串、解构、模块化、Promise、Symbol | 现代化语法革命 | 现代前端框架(React/Vue)开发基础 |
| ES7 | 2016 | Array.includes()、指数运算符(\*\*) | 工具方法补充 | 数组操作、数学计算 |
| ES8 | 2017 | async/await、Object.values()/entries()、字符串填充(padStart) | 异步流程控制 | 异步请求处理、对象数据转换 |
| ES9 | 2018 | for-await-of、对象 Rest/Spread、正则命名捕获组 | 异步迭代与对象操作 | 流式数据处理、复杂正则匹配 |
| ES10 | 2019 | Array.flat()/flatMap()、Object.fromEntries()、可选 catch 参数 | 数据操作简化 | 嵌套数据扁平化、错误处理简化 |
| ES11 | 2020 | Promise.allSettled()、可选链(?.)、空值合并(??)、BigInt | 安全访问与大数据支持 | 防御性编程、大整数运算 |
| ES12 | 2021 | 逻辑赋值运算符(`=/&&=)、String.replaceAll()、WeakRef`、 | 语法糖与内存管理、代码简化、缓存优化 | |
| ES13 | 2022 | 类私有字段/方法、Array.at()、顶层 await、Error.cause | 封装性与工程化 | 模块化开发、错误链式追踪 |
| ES14 | 2023 | Array.findLast()、toReversed()、Object.groupBy()、Hashbang 标准化 | 不可变操作与数据分组 | 数据聚合分析、不可变数据场景 |
## 主要演进路线
关键演进路线
1. 从 ES5 到 ES6
* 跨越式升级:从基础功能到现代化语法(如箭头函数、类、模块化)。
* 影响:奠定现代 JavaScript 开发基础,推动前端工程化。
2. ES7-ES10
* 渐进增强:填补工具方法(如数组/对象操作)、优化异步编程(async/await)。
* 目标:提升开发效率和代码可读性。
3. ES11-ES14
* 精细化改进:安全访问(可选链)、内存管理(WeakRef)、不可变数据操作。
* 趋势:面向大型应用开发与性能优化。