不经一番寒彻骨,怎得梅花扑鼻香。要耐心看下去哦!相信你终有所得!
ES6
Let Const 定义
let的使用:
- 变量不能重复声明(var可以) ;
- 块级作用域;
- 存在变量提升(在定义语句之前使用变量,var可以)存在这个过程,但是结果是不赋值的;
- 不影响作用域链效果(可闭包);
const的使用:
- 一定要赋初始值,否则报错;
- 定义的常量为大写(潜规则);
- 常量的值不能修改;
- 块级作用域;
- 对数组和对象内属性的修改不算对常量的修改(指向的地址没改变);
注: 在没定义使用变量时,报语法错误; 在定义但没初始化时默认赋值undefined; 赋值为null时,既没指向也没值,输出为null,所以当声明不确定的变量时,尽量写null;
解构赋值
- 数组解构([ ])
let F4 = ['刘能','赵四','宋小宝','小沈阳'];
let [liu, zhao, song, xiao] = F4;
- 对象解构({})
let team = null
const ZHAO = {
name: '赵本山',
age: '*',
team: 'F4',
skill: {
song: '',
dance: '',
rap: '',
},
xiaoPin() {
console.log(this)
},
}
/**
* sex = '明白' ---- 给解构的变量设置默认值
* age:localtion ---- 解构对象属性赋值给不同名变量
* skill:{song, dance, rap} ---- 嵌套对象的解构
*/
// ({team} = ZHAO);
let {name, sex = '明白', xiaoPin, age: localtion,skill: { song, dance, rap }} = ZHAO
console.log(team)
console.log(name)
console.log(sex)
xiaoPin() // window
// console.log(age); //age is not defined
console.log(localtion)
// console.log(skill); // skill is not defined
console.log(song, dance, rap) // ''
注: 深浅拷贝取决于变量的内部属性,如内部属性为基础数据类型则为深拷贝,否则为浅拷贝; this的指向变了;不是顺序赋值,是同名赋值;
模板字符串(`` , ${})
- 声明;
- 可以直接换行,不用换行符(\n);
- 变量拼接;
简写对象
- 简写键值对
let name = '钱';
let fun = () =>{ }
let obj = {
name,
fun
}
- 在对象中简写方法(去掉了function)
const OBJ ={
fun2(){}
}
箭头函数
- 声明一个函数,省略写法和箭头写法不是一个东西,省略写法的this没变
let fun = function() {};
function fn() {};
let fun = () =>{ };
- this是静态的,始终指向函数声明时所在的作用域的this值,用call也改不了;
- 不能作为构造函数实例化对象;
- 不能使用arguments变量;
- 箭头函数的简写, 省略小括号(有参数且只有一个参数)和花括号(有一行js代码);
- 只有一行语句,可省略大括号和return,自动return。
函数的参数
- 形参初始值
function add(a, b, c=10){ }
- rest参数获取实参(es5 为 arguments), 与es5的不同是这个可以使用这些数组方法
function add(...args) {
console.log(args) // fifter、map、every、some
}
add(1,2,3,4)
arguments和 rest的区别:
- arguments是伪数组, args是真数组;
- args是自己起的名,可以随便叫, arguments不行;
- args必须写在括号中,且放到最后面,否则报语法错误;
- arguments包含所有传进来的参数值, rest只包含未被命名的参数值;
扩展运算符(...)
转化为参数序列,用','分开
let F4 = ['刘能', '赵四', '宋小宝', '小沈阳'];
const ZHAO = ['赵本山', ...F4]; //['赵本山', '刘能', '赵四', '宋小宝', '小沈阳'];
应用: 数组的合并、克隆,将伪数组转化为真数组;
注: 如果扩展的数组中有 引用类型的参数 , 那么此拷贝为浅拷贝
symbol数据类型
- 值是唯一的,可以用来解决命名冲突问题(我们不可见);
- symbol值不能与其他类型进行运算;
- symbol的对象属性不能用 for... in 进行循环,但是可以用reflect.ownKeys来获取对象的所有键名;
- symbol具有11个内置 属性
1. 自动随机
let sym = Symbol();
2. 描述字符串,并不是symbol的值,每次返回的值也不是一样的;下面两个变量虽然一样,但是值并不一样
let sym = Symbol('随机且不重复的数')
let sym = Symbol('随机且不重复的数')
3.下面两个变量是一样的,返回值也一样;for的情况下在全局作用域内进行搜索;
let sym = Symbol.for('随机且不重复的数')
let sym = Symbol.for('随机且不重复的数')
迭代器与生成器(async 与 await的原生)
迭代器(iterator接口)
1、推荐在循环对象属性的时候使用 for...in,在遍历数组的时候的时候使用 for...of
2、for...in 循环出的是 key,for...of 循环出的是 value
3、注意,for...of 是 ES6 新引入的特性。修复了 ES5 引入的 for...in 的不足
4、for...of 不能循环普通的对象(如通过构造函数创造的),需要通过和 Object.keys()搭配使用
for(let item of obj){ } // item 为键值或元素
for (let item in obj) { } // item 为键名或索引
- 工作原理
创建一个指针对象,指向当前数据结构的起始位置 第一次调用对象的next方法,指针自动指向数据结构的第一个成员; 接下来不断调用next方法,指针不断向后移,直到指向最后一个; 每调用next方法返回一个包含value和done属性的对象;
const F4 = {
name: '赵家班',
member: ['刘能', '赵四', '宋小宝', '小沈阳'],
[Symbol.iterator](){
let index = 0;
return{
next:() =>{
if(index < this.member.length){
let result ={value: this.member[index], done: false}
index ++ ;
return result ;
}else{
return {value: undefined, done: true}
}
}
}
}
}
for(let m of F4){
console.log(m) // 刘能 赵四 宋小宝 小沈阳
}
自定义对象要想到迭代器
生成器(generator)
定义:一个特殊的函数 声明特殊,调用特殊。与迭代器连用
- yield: 分割一个单独的作用域
function * gen(){
console.log(1);
yield `我来分割`;
console.log(2);
yield '我也来';
console.log(3);
}
let iterator = gen();
// iterator.next(); // 输出1
// iterator.next(); // 输出2
// iterator.next(); // 输出3
console.log( iterator.next()); //输出 1 {value: '我来分割', done: false}
console.log( iterator.next()); //输出 2 {value: '我也来', done: false}
console.log( iterator.next()); //输出 3 {value: undefined, done: true}
for(let v of gen()){
console.log(v) // 输出 1 我来分割 ...
}
- 生成器函数参数的传递 参数依次往前提,当做前一个yield的值,可以在后面使用
function * gen(arg){
console.log(arg);
let A = yield `我来分割`;
console.log(A);
let B = yield '我也来';
console.log(B);
}
let iterator = gen('AAA');
console.log( iterator.next('BBB')); //输出 AAA {value: '我来分割', done: false}
console.log( iterator.next('CCC;)); //输出 BBB {value: '我也来', done: false}
console.log( iterator.next('DDD')); //输出 CCC {value: undefined, done: true}
- 异步编程的实用 解决回调地狱
let n = 0;
function one(){
setTimeout(() =>{
console.log(n++);
iterator.next()
}, 1000)
}
function two(){
setTimeout(() =>{
console.log(n++);
iterator.next()
}, 1000)
}
function three(){
setTimeout(() =>{
console.log(n++);
iterator.next()
}, 1000)
}
function * gen(){
yield one();
yield two();
yield three();
}
let iterator = gen();
iterator.next()
模拟获取用户数据 => 获取订单数据 => 获取商品数据
将上一次的值通过next传参就能获取上一次得到的值
Set集合
定义:类似于数组,但每个成员都是唯一的;且集合了iterator接口,可以使用for of 和 ... 扩展运算符进行遍历(三类数据结构原生具备Iterator接口:数组、某些类似数组的对象、Set和Map结构。)
- 声明及方法
let S = new Set() // 声明
let arr = ['1', '2', '3', '2', '1'];
let unrepeatedArr = new Set(arr); // 不改变原数组
console.log(unrepeatedArr)
console.log(unrepeatedArr.size); //set集合的长度,类似于length
unrepeatedArr.add('5') // 添加一个元素,添加重复得元素不生效
console.log(unrepeatedArr);
unrepeatedArr.delete('5') //删除一个元素,删除里面没有的元素不报错
console.log(unrepeatedArr);
console.log(unrepeatedArr.has('2') ); //查找元素, 返回Boolean值
unrepeatedArr.clear(unrepeatedArr) //清空元素
console.log(unrepeatedArr);
- 实际应用
求交集:
let arr = ['1', '2', '3', '2', '1'];
let ARR = ['1', 2, '4'];
let mixArr = [...new Set(arr)].filter(item => {
let ARRSet = new Set(ARR);
if (ARRSet.has(item)) return true;
else return false;
})
console.log(mixArr) // 1
并集: 方法太多了
1. 用add
2.先合并数组再去重
差集: A里有B中没有的或反过来
交集取反就好了
map结构
定义:ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了字符串—值的对应,Map 结构提供了值—值的对应,是一种更完善的 Hash 结构实现。也实现了iterator接口和...扩展。 注: 对象的结构 本质上是键值对的集合(Hash 结构),但是传统上只能用字符串当作键。
const m = new Map();
const o = {p: 'Hello World'};
m.set(o, 'content')
m.get(o) // "content"
m.has(o) // true
m.delete(o) // true
m.has(o) // false
属性:
- size:返回字典所包含的元素个数
操作方法:
- set(key, val): 向字典中添加新元素
- get(key):通过键值查找特定的数值并返回
- has(key):如果键存在字典中返回true,否则false
- delete(key): 通过键值从字典中移除对应的数据
- clear():将这个字典中的所有元素删除
遍历方法:
- keys():将字典中包含的所有键名以数组形式返回
- values():将字典中包含的所有数值以数组形式返回
- forEach():遍历字典的所有成员
数值扩展方法
- Number.EPSILON:JavaScript表示的最小值,可用来提高精度,值为2.220446049250313e-16;
- 进制: 2进制:0b ; 8进制:0O ; 16进制:0x;
- Number.isFinite(num):检测一个数值是否为有限数,返回值为Boolean,是为true;
- Number.isNAN(num):检测一个数值是否为NAN,ES5中是一个单独的函数,但现在放在number中,是为false;
- Number.parseInt(num), Number.parseFloat(num):将字符串转化为数值型,如果字符串以字母开头将字符串转化为NAN。
- parseInt将字符串转化为整数,但不会保留小数位,且不会有进位;
- parseFloat将字符串保留为小数类型,只识别第一个小数点;
- Number.isInteger(num): 判断数值是否为整数,是为true,不识别字符串;
- Math.trunc(num): 将数字保留为整数,可以识别字符串;
- Math.sign(num): 判断一个数值是否为正数、 0 、 负数,可以识别字符串;正数返回值为1, 负数返回值为-1,0 返回值为0。
对象的扩展方法
- Object.is(obj1, obg2): 判断两个值是否完全相等,类似于===,但是在判断NAN是否等于NAN时,返回为true;
- Object.assign(obj1, obj2): 将后面的对象向前面的对象合并,
- 如果对象只有一层为深拷贝,如果对象为多层为浅拷贝。
- 会改变原被合并的对象obj1,,返回值为合并后的obj1;
- Object.setPrototypeOf(obj1,obj2),Object.getPrototypeOf(obj1):设置对象原型
- tPrototypeOf是将obj2的值插入obj1的原型中;
- getPrototypeOf得到的值为obj2的值;
模块化
优势: 防止命名冲突,代码复用,高维护性。
export暴露导出
1. 分别暴露:分别导出A和B,如果要导出必须在定义的时候导出,不能导出变量否则报错;
export let A = '1';
export let B = '2';
2. 统一暴露: 这样可以导出变量
export{
A: A,
B
}
3. 默认暴露
export default C;
import引入
1. *代表全部导入、 as取别名,demo为对象包含分别暴露的信息
import * as demo from './src/demo.js';
2. 多个暴露可以解构, 也可以用as取别名
import {A , B} from './src/demo.js';
3. 默认暴露的使用,需要 + defalut
import * as demo from './src/demo.js';
demo.defalut.C
4. 默认暴露解构的情况, demo就是默认导出的对象
import {defalut as demo} from './src/demo.js';
demo.C
5. 默认暴露简便形式,只针对默认暴露, demo就为对象
import demo from './src/demo.js';
demo.C
注: import引入和require引入 import demo from './src/demo.js' = const demo = require('./src/demo.js')
babel转换为es5
安装、转义、打包
ES7
方法扩展
- Arr.includes(元素): 检查数组中是否含有该元素,返回值为boolean;(indexof也能实现,但返回为下标)
- num1 ** num2: 指数操作,和Math.pow(num1,num2)一样;
ES8
async, await
- async 的返回值为promise对象,promise的状态及结果由函数的return值决定。
1. 返回值为字符串或其他
async function fun(){
return '任何一个值或空'
}
console.log(fun()) // 返回一个成功状态的promise
2. 抛出一个错误
async function fun1(params) {
throw new Error('我现在错误了')
}
console.log(fun1()); //返回一个错误的promise
3. 返回一个promise
async function fun2(params) {
return new Promise((resolve, rejected) =>{
resolve('我想成功')
})
}
console.log(fun2()); // 返回一个成功的promsie
- await:在await右侧的表达式走完之前,js不向下走。 await必须放在async内; await右侧的表达式通常是promise对象; await返回的是promise成功的值; await的promise失败时,抛出错误,需0要用try{}catch{}接收;
let p = new Promise((resolve, rejected) => {
resolve('我输入的值')
})
async function fun() {
let result = await p;
console.log(result) // 值为我在resolve中输入的值
}
async function fun1(){
try{
let result = await p;
console.log(result)
}catch(err){
console.log(err)
}
}
fun()
对象方法的扩展
- Object.keys(obj), Object.values(obj): keys获取的是obj对象的键, values获取的是值,返回的是数组。
- Object.entries(obj):返回值为数组,并且每个数组的元素都是对象的键值对,这个键值对的格式也是数组,方便创建map结构。(二维数组)
- create, getOwnPropertyDescriptor
const obj = Object.create(null, { // 第一个参数为原型对象, 第二个为描述对相关
name: {
value: '用到的',
writable:true,
configurable:true,
enumerable: true
}
})
console.log(Object.getOwnPropertyDescriptor(obj)) //获取描述对象
ES9
对象扩展
- rest 见上面ES6部分,ES6只是针对于数组,现在也是支持对象。
- ...对象的扩展运算符,返回值为用‘ ,’分割的键值对,用法和上面数组的扩展一样;
正则扩展
- () , ?: 字符串的分组、 命名结果; 通过reg.exec(str)获取结果;
- 正向断言: 根据后面的值,判断前边的内容是不是合法的;
- 反向断言:根据前边的值,判断后面的内容是否是合法的;
- dotall: 匹配任意字符;
ES10
对象扩展
- Object.fromEntries(arr): 将二维数组转化为对象,为ES8中Object.entries(obj)的逆运算;(二维数组只转化2个元素,第一个元素当键名,第二个元素当键值,后面的不管)
字符串扩展
- str.trimStart(), str.trimEnd():清除字符串空格start为左侧,end为右侧,中间的不管;(trim方法全部清除,中间的也不管)
数组扩展
- arr.flat(2):将多维数组转化为低维数组,参数决定维数;
- arr.flatMap( () => {} ) : flat + map的结合; (map的返回值为操作的数组,包括在方法内对数组进行的操作)
symbol扩展
- Symbol.prototype.description(s): 获取symbol格式的s的原型描述
ES11
静态属性
- #: 静态属性简写
promise扩展
- promise.allSettled([P1, P2] ):调用并得到多个promise的返回值,返回值为一个成功的promise,这个promise的值为数组,每个元素为执行的promise的值,如果某个promise执行失败, promise.allSettled([P1, P2] )依旧会的到一个成功的promise,但是那个失败的promise的值变为抛出的错误。
字符串方法扩展
- str.matchAll():正则批量匹配的结果,数据的批量提取;
可选链操作符
?. : 避免无意义的报错。在做层层判断时,当一个值不传时,代码会报错,但是用 ?. 可选链式操作符,就会输出undefined
!. :TypeScript的语法,叫非空断言操作符(non-null assertion operator),和?.相反,这个符号表示对象后面的属性一定不是null或undefined。
动态import加载
使用
function fun(params) {
import('./a.js').then( module => { // 返回一个promise
console.log(module) // 其中包括文件a.js导出的对象
})
}
fun()
BigInt 大整形,新的基础数据类型
- 定义声明: 在数据后 + n
let n = 123n;
console.log(typeof(n)); // bigint
- BigInt方法: 将整数转换为bigint型,但不包括浮点型。
let n = 123;
console.log(BigInt(n)); // 将数字型转化为bigint型
- 用处: 大数值运算
js存在最大值Number.MAX_SAFE_INTEGER,在这个值之后不能再进行运算,但是BigInt型的数据可以继续运行;