一.什么是ES?
全称:ECMAScript
ES可以说是一种定义JS的语法规范的标准
二.ES6(vue和react使用的ECMA版本都是ES6)
2.1 let声明变量
let a;
let a,b,c;
let e = 100;
let f = 500, g = 600;
注意:①变量不能重复声明
②块级作用域,只能在代码块里面有效
③不存在变量提升 不允许在变量声明前使用变量
④不影响作用域链的效果
2.2 const声明常量
const school = '中国石油大学(华东)';
注意:①一定要赋初始值
②一般常量使用大写(潜规则,不是语法要求)
③常量值不能修改
④块级作用域
⑤对于数组和对象的元素修改,不算对常量的修改,不会报错
const TEAM = ['WADE','BOSH','JAMES']
TEAM.push('BUTLER');
2.3 解构赋值
①数组的解构
const TEAM = ['WADE','BOSH','JAMES']
let [a,b,c] = TEAM;
console.log(a);
console.log(b);
console.log(c);
②对象的解构
const me = {
'name':'你爸爸',
'age':'28',
'call':function () {
console.log('叫我爸爸!');
}
}
let {name,age,call} = me;
console.log(name);
console.log(age);
call();
2.4 模板字符串
新的声明字符串的方式 [``],'',""
①声明
let str = `这是一个字符串`;
②内容中可以直接出现换行符
let str = `<ul><li>韦德</li><li>詹姆斯</li><li>波什</li><ul>`
③变量拼接
let str = `为什么在南京?`;
let str2 = `${str}因为领导们都是傻逼`;
console.log(str2);
2.5 ES6允许在大括号里面直接写入变量和函数作为对象的属性和方法
let str = `为什么在南京?`;
let str2 = `${str}因为领导们都是傻逼`;
const sb = {
str,
str2,
call(){
console.log('全你妈是傻逼!');
}
}
console.log(sb.str);
console.log(sb.str2);
sb.call()
2.6 箭头函数及其声明特点
let fn = ()=>{};
①this是静态的,this始终指向函数声明时所在的作用域下的this的值,函数声明在哪里永远都不会变
②不能作为构造实例化对象
③不能使用arguments变量
④箭头函数的简写
1)省略小括号,当形参有且只有一个的时候
2)省略花括号,当代码有且只有一条语句的时候
2.7 ES6允许给函数参数赋值初始值
传了就用传的值,不传就用默认值
1.形参初始值,具有默认值的参数,一般位置要靠后(潜规则)
function add(a,b,c=10){
return a+b+c
}
let result = add(1,2);
console.log(result)
2.与结构赋值结合
function content({name='傻逼',age,sex,job}){
console.log(name);
console.log(age);
console.log(sex);
console.log(job);
}
content({
name:'阿文',
age:45,
sex:'不详',
job:'恶心人'
});
2.8 rest参数
ES5获取实参的方式,arguments
function data(){
console.log(arguments);
}
data('阿文','阿东','阿张','阿波','阿立','阿杨')
ES6 rest参数并且rest参数必须放到参数最后
function data(...args){
//数组
console.log(args);
}
data('阿文','阿东','阿张','阿波','阿立','阿杨');
function data(a,b,...args){
//数组
console.log(args);
}
data('阿文','阿东','阿张','阿波','阿立','阿杨');
2.9 扩展运算符 [...]
[...]扩展运算符能将[数组]转换为逗号分隔的[参数序列]
const arrList = ['阿文','阿东','阿张','阿波','阿立','阿杨'];
function sayName(){
console.log(arguments)
}
sayName(...arrList); // sayName('阿文','阿东','阿张','阿波','阿立','阿杨');
扩展运算符的应用
1.数组的合并
const sb1 = ['阿文','阿东','阿张'];
const sb2 = ['阿波','阿立','阿杨'];
数组的合并:[...sb1,...sb2]
2.数组的克隆
const sb1 = ['阿文','阿东','阿张'];
const sb2 = [...sb1];
3.将伪数组转换为真正的数组
2.10 symbol基本使用
ES6引入的新的原始数据类型,表示独一无二的值
ES6有七中数据类型:
usonb:理解你非常牛逼
u:undefined
s:string symbol
o:object(对象,数组都属于object)
n:null umber
b:boolean
2.10 Promise
Promise是ES6引入的异步编程的新解决方案
2.11 集合Set
类似于数据,但是成员的值都是唯一的
let s = new Set(['阿张','阿东','阿文','阿张','阿志','阿远']);
console.log(s); // ['阿张','阿东','阿文','阿志','阿远']
①size元素个数
console.log(s.size); // 5
②add添加新元素,返回当前集合
console.log(s.add('阿超'));
③delete删除元素,返回boolean类型
console.log(s.delete('阿超'));
④has包含元素,返回boolean类型
console.log(s.has('阿远'));
实践:
let arr = [1,2,3,4,5,4,3,2,1];
①数组去重
let result = [...new Set(arr)];
console.log(result)
②交集
let arr2 = [4,5,6,5,6];
let result = [...new Set(arr)].filter(item=> new Set(arr2).has(item));
③并集
let union = [...new Set([...arr,...arr2])];
console.log(union);
④差集
let diff = [...new Set(arr)].filter(item=> !(new Set(arr2).has(item)));
console.log(diff);
2.12 Map
ES6提供了Map数据结构,类似于对象,也是键值对的集合,但是键的范围不限于字符串,各个类型的值都可当作键
//声明Map
let m = set Map();
①添加元素 set
m.set('name','都傻逼');
console.log(m);
let key = {'产品':'都傻逼'};
m.set(key,['张某某']);
②获取个数size
console.log(m.size);
③删除delete
m.delete('name');
④获取 get
m.get('name');
⑤清空
m.clear();
2.13 class类
ES6提供了更加传统语言的写法,引入Class(类)这个概念,作为对象的模版,通过class关键词,可以定义类.
基本上,ES6的class可以看作只是一个语法糖,他的绝大多数功能,ES5都可以实现,新的class写法只是让对象
的原型更加清晰,更像面向对象编程的语法而已.
知识点
1)class 生命周期
2)constructor定义构造函数初始化
3)extends继承父类 class ChildClass extends ParentClass{}
4)super调用父类构造方法
5)static定义静态方法和属性 new的实例对象不能调用,只有class可以调用
6)子类中可以重写父类方法
2.13.1 继承:
class fartherPhone {
constructor(name,price) {
this.name = name;
this.price = price;
}
call(){
console.log('别给我打电话!');
}
}
class sonPhone extends fartherPhone{
constructor(name,price,color,size) {
super(name,price);
this.color = color;
this.size = size;
}
photo(){
console.log('敢偷拍,滚!');
}
call(){
console.log('就打就打就打!');
}
}
const xiaomi = new sonPhone('小米','1999','黑色','8');
console.log(xiaomi);
xiaomi.call();
xiaomi.photo();
2.13.2 class的get和set
class Phone {
get price(){
console.log('好贵啊!');
return 19999;
}
set price(price){
console.log('价格来了!');
}
}
// 实例化对象
let s = new Phone();
console.log(s.price) //调用get,返回值return的返回值
s.price = '18888'; //调用set
2.14 数值扩展
①Number.EPSILON是JS标示的最小精度
②二进制OB1010 八进制0o777 十进制 100 十六进制 0xff
③Number.isFinite 检测一个数值是否为有限数 Number.isFinite(100) //true
④Number.isNaN 检测一个数值是否为NaN
⑤Number.parseInt Number.parseFloat字符串转整数
⑥Number.isInteger 判断一个数是否为整数
⑦Math.trunc将数字的小数部分抹掉
⑧Math.sign 判断一个数到底是正数返回1 负数返回-1 还是 零返回0
2.15 对象方法扩展
①Object.is 判断两个值是否相等
object.is(NaN,NaN) //true
NaN === NaN //false
②Object.assign 对象的合并
③Object.setPrototypeOf 设置原型对象
Object.getPrototypeOf 获取原型对象
2.16 ES6模块化
模块化指将一个大的层序文件,拆分成多个小的文件,然后将小的文件组合起来
模块化的好处:1)防止命名冲突 2)代码复用 3)高维护性
ES6模块化语法
1)export命令用于规定模块的对外接口
①单独包括:
export function call() {
console.log('叫你傻逼');
}
②统一暴露
function call() {
console.log('叫你傻逼');
}
let name = '阿文';
export {
call,
name
}
③默认暴露
export default {
name:'阿文',
call:function () {
console.log('叫你傻逼');
}
}
使用:phone.default.call();
2)import命令用于输入其他模块提供的功能
<script type="module">
import * as a from './phone.js';
a.call();
</script>
①通用的导入方式
import * as a from './phone.js';
②解构赋值暴露
import {name,call} from './phone.js';
import {default as phone} from './phone.js'; //默认暴露使用 调用:phone.call()
import phone from './phone.js'; //针对默认暴露 调用:phone.call()
3)多模块引用
创建一个app.js
import * as a1 from './a1.js';
import * as a2 from './a2.js';
import * as a3 from './a3.js';
界面使用:
<script src="./app.js" type="module"></script>
2.17 babel对ES6模块化代码转化和打包
①安装 npm i babel-cli babel-preset-env browserify (简单) / webpack(项目中使用)
② npx babel src/js -d dist/js --presets=babel-preset-env
③ 打包 npx browserify dist/js/app.js -o dist/bundle.js
2.18 迭代器(接口,为数据结构提供访问机制)
迭代器是一种接口,为各种不同的数据结构提供统一的访问机制,任何结构数据只要部署iterator接口,就可以遍历操作.
ES6创造了新的遍历命令for...of循环
工作原理:
1)创建一个指针对象,指向当前数据结构的起始位置
2)第一次调用对象的next方法,指针自动指向数据结构的第一个成员
3)接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员
4)没调用next方法返回一个包含value和done属性的对象
注意:需要自定义遍历数据的时候,要想到迭代器
2.19 生成器(函数,异步编程解决方案)
生成器函数是ES6提供的一种异步编程的解决方案,语法行为与传统函数完全不同
生成器函数声明:在function和函数名之间加一个*
function * gen(){}
三.ES7
3.1 Array.prototype.includes
includes方法用来检测数据中是否包含某个元素,返回布尔类型值
3.2 运算 **
2的十次方 2**10
四.ES8
async和await
async和await两种语法结合可以让异步代码像同步代码一样
4.1 async函数
①返回值为promise对象
②promise对象的结果值由async函数执行的返回值决定
4.2 await表达式
①await必须写在async函数中
②await右侧的表达式一般为promise对象
③await返回值是promise对象成功的值
④await的promise失败了,就会抛出异常,需要通过try..catch捕获处理
async和await的结合读取文件
const fs = require('fs')
//读取傻逼
function readSb(){
return new Promise((resolve,reject)=>{
fs.readFile("./sb.txt",(err, data) => {
if(err){
reject(err)
}
resolve(data)
} )
})
}
//读取小傻逼
function readLsb(){
return new Promise((resolve,reject)=>{
fs.readFile("./lsb.txt",(err, data) => {
if(err){
reject(err)
}
resolve(data)
} )
})
}
//读取大傻逼
function readBsb(){
return new Promise((resolve,reject)=>{
fs.readFile("./bsb.txt",(err, data) => {
if(err){
reject(err)
}
resolve(data)
} )
})
}
//声明一个async函数
async function read(){
let sb = await readSb();
let lsb = await readLsb();
let bsb = await readBsb();
console.log(sb.toString());
console.log(lsb.toString());
console.log(bsb.toString());
}
read();
4.3 对象方法扩展
let dic = {
name:'阿文',
father:['阿远','阿超','阿鹏'],
girl:['阿启']
}
4.3.1 获取对象所有的键
Object.keys(dic) //["name","father","girl"]
4.3.2 获取对象的所有的值
Object.values(dic) // ["阿文",["阿远","阿超","阿鹏"],["阿启"]]
4.3.3 entrise 对象转换为二维数组
Object.entrise(dic) // [["name","阿文"],["father",["阿远","阿超","阿鹏"]],["girl",["阿启"]]]
4.3.4 Object.getOwnPropertyDescriptors
返回指定对象所有自身属性的描述对象
五.ES9
5.1 扩展运算符与rest参数
为对象提供了像数组一样的rest参数和扩展运算符
①rest参数
function call({name,...people}) {
console.log(people); // {"father": ["阿远","阿超","阿鹏"],"girl": ["阿启"]}
}
let dic = {
name:'阿文',
father:['阿远','阿超','阿鹏'],
girl:['阿启']
}
call(dic)
②扩展运算符
const alldic = {...dic1,...dic2,...dic3}
5.2 正则扩展
①命名捕获分组
②反向断言
③dotAll模式
六.ES10
6.1 对象方法扩展
fromEntrise 二维数组转换为对象
6.2 字符串方法扩展
str.trimStart(); //清除左侧空白
str.trimEnd(); //清除右侧空白
6.3 数组方法和扩展
①flat 将多维数组转换为一维数组,参数为深度值,默认是1
const str = [1,2,[3,4]];
consolt.log(arr.flat()); //[1,2,3,4]
const str = [1,2,[3,4,[5,6]];
consolt.log(arr.flat(2)); //[1,2,3,4,5,6]
②flatMap
const str = [1,2,3,4];
console.log(str.flatMap(item => [item*10])); //[1,2,3,4]
6.5 Symbol.prototype.description
获取Symbol描述
七.ES11
7.1 私有属性
class Person{
// 公有属性
name;
// 私有属性
#age;
constructor(name,age) {
this.name = name;
this.#age = age;
}
}
const p = new Person('阿文','48')
console.log(p.name);
console.log(p.#age); //报错 Private field '#age' must be declared in an enclosing class
7.2 Promsie allSettled方法
const p = new Promise((resolve,reject) => {
resolve('成功了!')
})
const p1 = new Promise((resolve,reject) => {
resolve('又成功了!')
})
const result = Promise.allSettled([p,p1])
console.log(result);
//结果
{
PromiseState:fulfilled,
PromiseResult:[
{
"status": "fulfilled",
"value": "成功了!"
},
{
"status": "fulfilled",
"value": "又成功了!"
}
]
}
const p = new Promise((resolve,reject) => {
resolve('成功了!')
})
const p1 = new Promise((resolve,reject) => {
reject('失败了!')
})
const result = Promise.allSettled([p,p1])
console.log(result);
//结果
{
PromiseState:fulfilled,
PromiseResult:[
{
"status": "fulfilled",
"value": "成功了!"
},
{
"status": "rejected",
"value": "失败了!"
}
]
}
7.2 String.prototype.matchAll方法
得到正则批量匹配的结果
7.3 可选链操作服务 ?.
config && config.db && config.db.host => config?.db?.host
7.4 动态import
import('./hello.js').then{module => {
module.hello();
}}
7.5 新的数据类型BigInt
let n = 521n;
将整形转换为大整形
let n = 521;
BigInt(n);
let max = Number.MAX_SAFE_INTEGER;
console.log(BigInt(max) + BigInt(1));
7.6 绝对全局对象
globalThis
八.ES12
8.1 字符串方法replaceAll()
找到所有符合的字符串然后替换掉
8.2 逻辑赋值操作符:??=,&&=,||=
①||= 或赋值运算符 一真全真
let id = '';
id = id || 99;
console.log(id) // 99
变为:
id ||= 99;
console.log(id) // 99
②&&= 与赋值运算符 一假全假
let id = '';
id = id && 99;
console.log(id) // ''
变为:
let id = 100;
id &&= 99;
console.log(id) // 99 都有值返回右边的赋值
③??= Null赋值运算符
let obj = null;
obj ??= 999;
console.log(obj) // 999
8.3 数字分隔符,不仅可以分隔数字也可以分隔二进制,十六进制等
let n = 123456789;
let n2 = 123_456_789;//分隔符提高可读性
8.4 Promise.any
Promise.any([p1,p2,p3]) //只有一个先完成就执行then,等到所有的都失败了才执行catch
九.ES13
9.1 数组的方法at()
根据下标返回对应的元素,可以返回整数和负数
let arr = [1,2,3,4,5,6];
console.log(arr.at(1)); // 2
console.log(arr.at(-2)); // 5
十.ES5
10.1 json对象扩展
JSON.stringify(arr/obj); //js对象(数组)转换为json对象(数组)
JSON.Parse(json); //json对象(数组)转化为js对象(数组)
10.2 Object对象方法扩展
①Object.create(prototype,[descriptors])
作用:以指定对象为原型创建新的对象
为新的对象指定新的属性,并对属性进行描述
-value:指定值
-writable:标识当前属性值是否是可修改的,默认为false
-configurable:标识当前属性是否可删除,默认为false
-enumerable:标识当前属性是否能用for in 枚举.默认为false
var obj = {name:'阿文',age:48};
var obj1 = Object.create(obj,{sex:{value:'不男不女',writable:true,configurable:true,enumerable:true}})
console.log(obj1)
②Object.defineProperties(object,descriptors)
作用:为指定对象扩展多个属性
get:用来获取当前指定值得到回调函数
set:修改当前值触发回调函数,并且实参为修改后的值
存取器熟悉:setter,getter一个用来存值,一个用来取值
var obj = {name:'阿文',age:48};
Object.defineProperties(obj,{
fullName:{
get:function (){ //获取扩展属性的值,获取扩展属性值get方法自动调用
return '名字' + this.name + ',年龄'+ this.age;
},
set:function (data){ //监听扩展属性,当扩展属性发生变化的时候自动回调
console.log(data);
}
}
})
console.log(obj.fullName); //调用get,名字阿文,年龄48
obj.fullName = '张**'; //调用set,data为张**
console.log(obj.fullName); //不能修改,名字阿文,年龄48
10.2 数组的扩展扩展
Array.prototype.indexOf(value);//得到值在数组中的第一个下标
Array.prototype.lastIndexOf(value);//得到值在数组中的最后一个下标
Array.prototype.forEach(function (item,index) {});//遍历数组
Array.prototype.map(function (item,index) {});//遍历数组,返回一个新的数组,返回加工后的值
Array.prototype.filter(function (item,index) {});//遍历过滤出一个新的子数字,返回条件为true的值
let arr = [1,2,3,4,5]
console.log(arr.indexOf(1)); //0
console.log(arr.lastIndexOf(1)); //0
arr.forEach(function (item,index) {})
let arr2 = arr.map(item=>item*100)
console.log(arr2); //[100,200,300,400,500]
let arr3 = arr.filter(item => item<3)
console.log(arr3); //[1,2]
10.3 Function的扩展call,apply,bind
call,apply,bind的区别?
①都能指定函数中的this
②call()/apply() 是立即调用函数
③bind()是将函数返回
Function.prototype.bind(obj);
将函数中的this绑定为obj,并将函数返回
function jian(data,data2){
console.log(this);
console.log(data);
console.log(data2);
}
jian({name:'阿文',age:48}) //this为window,data为传入的obj
//传入参,直接从第二个参数开始,依次传入
jian.call({name:'阿文',age:48}) //this为传入的obj,data和data2为undefined
jian.call({name:'阿文',age:48},[1,2,3],1) //this为传入的obj,data为[1,2,3],data2为1
//传入参,第二个参数必须是数组,传入的放到数组里
jian.apply({name:'阿文',age:48}) //this为传入的obj,data和data2为undefined
jian.apply({name:'阿文',age:48},[[1,2,3],2]) //this为传入的obj,data为[1,2,3],data2为2
//传入参,直接从第二个参数开始,依次传入
let fn = jian.bind({name:'阿文',age:48},1,2); //不会调用函数
fn(); //调用函数 this为传入的obj,data为1,data2为2
简写:jian.bind({name:'阿文',age:48},1,2)();
定时器的this是window,不想让他是window
setTimeout(function () {
console.log(this);
}.bind({name:'阿文',age:48}),1000)