ES6
1.const let
- const 值是固定的(常量)
需要赋初始值
块级作用域
在数组里面,const的值是允许被修改的,这是因为const存储的是地址,值的内容可以变化
- let 声明的变量具有块作用域的特征。
在同一个块级作用域,不能重复声明变量。
声明的变量不存在变量提升,换一种说法,就是 let 声明存在暂时性死区(TDZ)。
js里对象(引用数据类型)是地址,常量对象地址不能改变,里面的属性可以改变
- var 有变量提升:先把var定义的内容(赋值不提)提在最前面;
使用
2. 箭头函数
()=>{}
- 不绑定this
本身没有this 里面的this指的是定义时的上层作用域的this
通过call、apply调用箭头函数
由于箭头函数没有自己的this指针,通过call()、apply()方法调用时,第一个参数会被忽略。
- 箭头函数没有 arguments( 普通函数的参数列表,是一个类数组对象 )
- 不能当构造函数
- 没有原型
3. rest参数 浅拷贝
…是为了让你不覆盖,是追加的意思.function date(...args){} //数组date('1','2','3')
- 扩展运算符
ES9 为对象提供了像数组一样的rest参数和运算符
//除了a,b 其他都是cfunction fn({a,b,...c}){}
4. Iterator 迭代器
- 一种接口,目的是为不同的数据结构提供统一的数据访问机制
- 只有实现了 Iterator接口的对象才能够使用 for of 来进行遍历取值
- 已默认部署 Iterator 接口的对象主要包括数组、字符串、Set、Map 、类似数组的对象(比如 arguments 对象、DOM NodeList 对象)。
- 默认调用Symbol.iterator方法:
- 解构赋值
- 扩展运算符
- yield* 关键字
Symbol.iterator 是一个表达式,返回 Symbol 对象的 iterator 属性,这是一个预定义好的、类型为 Symbol 的特殊值。
function createIterator(items) {let i = 0;return {next: function() {var done = (i >= items.length);var value = !done ? items[i++] : undefined;return {done: done,value: value};}};}
5. Generator 生成器
Generator 函数是 ES6 提供的一种异步编程解决方案
- function关键字与函数名之间有一个星号
- 通过yield关键字可以暂停执行
- 通过next方法才会遍历到下一个内部状态
- 因为Generator函数返回Iterator对象,因此我们还可以通过for…of进行遍历
调用return方法后,函数直接被终止。然后将传入的值作为迭代器对象的value,并且将done改为true。
function* gen() {yield 1yield 2yield 3}const g = gen()console.log(g.next()) // { value: 1, done: false }console.log(g.next()) // { value: 2, done: false }console.log(g.next()) // { value: 3, done: false }console.log(g.next()) // { value: undefined, done: true }
使用场景:
6.promise
概念:
Promise是为了解决回调地狱而产生的,将回调函数的嵌套,改成链式调用
链式操作减低了编码难度
-
状态:
promise对象仅有三种状态:pending(进行中),fulfilled(已成功),rejected(已失败)
对象的状态不受外界影响,只有异步操作的结果,可以决定
一旦状态改变(从pending变为fulfilled和从pending变为rejected),就不会再变,任何时候都可以得到这个结果
参数:
resolve,将Promise对象的状态从“未完成”变为“成功”(pending变为fulfilled)
reject,将Promise对象的状态从“未完成”变为“失败”(pending变为rejected)
实例方法:
then()
- catch() // 处理状态为rejected的回调函数
- finally()
- resolve() // 返回成功或者失败的Promise对象
- reject() // 返回一个失败的Promise对象
- all() // 用于多个 Promise 实例,两个或多个异步事件均完成后再触发回调,如果有失败,失败原因是第一个失败promise的结果
- race() // 只要有一个promise返回了就会结束 ( 图片请求超时
allSettled() // 并行地运行 promise,并将状态(fulfilled 或reject)收集到一个聚合数组中
一旦新建,立即执行,无法中途取消
- Promise内部抛出的错误,无法反映到外部
-
7.async
async/await作用是用同步方式,执行异步操作
- await只能在async函数中使用,不然会报错
async函数返回的是一个Promise对象,有无值看有无return值
// 先请求完接口1,再去请求接口2async function fn2() {await request(1)await request(2)}fn2()// 先请求完接口1,再拿接口1返回的数据,去当做接口2的请求参数async function fn () {const res1 = await request(5)const res2 = await request(res1)console.log(res2) // 2秒后输出 20}fn()
8.set && map
Set它类似于数组,但是成员的值都是唯一的,没有重复的值。
- Set 本身是一个构造函数,用来生成 Set 数据结构
-
new Set(iterable)—— 创建一个set,如果提供了一个iterable对象(通常是数组),将会从数组里面复制值到set中。set.add(value)—— 添加一个值,返回 set 本身set.delete(value)—— 删除值,如果value在这个方法调用的时候存在则返回true,否则返回false。set.has(value)—— 如果value在 set 中,返回true,否则返回false。set.clear()—— 清空 set。set.size—— 返回元素个数。
我们可以使用 for..of 或 forEach 来遍历 Set:
let set = new Set(["oranges", "apples", "bananas"]);for (let value of set) alert(value);// 与 forEach 相同:set.forEach((value, valueAgain, set) => {alert(value);});
Map 是一个带键的数据项的集合,就像一个 Object 一样。 但是它们最大的差别是 Map 允许任何类型的键(key)
它的方法和属性如下:
new Map()—— 创建 map。map.set(key, value)—— 根据键存储值。map.get(key)—— 根据键来返回值,如果map中不存在对应的key,则返回undefinedmap.has(key)—— 如果key存在则返回true,否则返回false。map.delete(key)—— 删除指定键的值。map.clear()—— 清空 map。map.size—— 返回当前元素个数。var m = new Map(); // 空Mapm.set('Adam', 67); // 添加新的key-valuem.has('Adam'); // 是否存在key 'Adam': truem.get('Adam'); // 67m.delete('Adam'); // 删除key 'Adam'm.get('Adam'); // undefined
Map 还可以使用对象作为键。
运行 forEach 函数
与普通对象Object的不同点:任何键、对象都可以作为键。
-
8.class
new会自动调用constructor()方法,因此我们可以在constructor()中初始化对象。
类字段重要的不同之处在于,它们会在每个独立对象中被设好,而不是设在User.prototype
Class 提供了"super"关键字。 执行
super.method(...)来调用一个父类方法。- 执行
super(...)来调用一个父类 constructor(只能在我们的 constructor 中)。
继承类的 constructor 必须调用 **super(...)**,并且 (!) 一定要在使用 **this** 之前调用。
受保护的属性通常以下划线 **_** 作为前缀。
get/set
class MyClass {prop = value; // 属性constructor(...) { // 构造器// ...}method(...) {} // methodget something(...) {} // getter 方法set something(...) {} // setter 方法[Symbol.iterator]() {} // 有计算名称(computed name)的方法(此处为 symbol)// ...}
//es5function phone(price,brand){this.price=price;this.brand=brand;}phone.prototype.call = function(){console.log("111");}let huawei = new phone(12222,'huawei');huawei.call();console.log(huawei);//es6 classclass shouji{constructor(price,brand){this.price=price;this.brand=brand;}call(){consolle.log("2222");}}let xiaomi = new shouji(12211,'xiaomi');console.log(xiaomi);
class Animal {constructor(name) {this.speed = 0;this.name = name;}run(speed) {this.speed = speed;alert(`${this.name} runs with speed ${this.speed}.`);}stop() {this.speed = 0;alert(`${this.name} stands still.`);}}class Rabbit extends Animal {hide() {alert(`${this.name} hides!`);}stop() {super.stop(); // 调用父类的 stopthis.hide(); // 然后 hide}}let rabbit = new Rabbit("White Rabbit");rabbit.run(5); // White Rabbit 以速度 5 奔跑rabbit.stop(); // White Rabbit 停止了。White rabbit hide 了!
静态属性和静态方法
我们可以把一个方法赋值给类的函数本身,而不是赋给它的 "prototype"。这样的方法被称为 静态的(static)。
class Person {name;age;static stand(){console.log("人类站起来了");}run() {console.log(`${this.age}岁的${this.name}跑起来了`);}}Person.stand();(new Person('张三',32)).run();(new Person('11',22)).run();
类继承 super()
//es5 构造函数继承function Person(sex,age){this.age=age;this.sex=sex;}Person.prototype.call = function(){console.log(1111);}function Chidren(sex,age,name,phone){Person.call(this,sex,age);this.name=name;this.phone=phone;}//设置子集构造函数的原型Chidren.prototype = new Person;Chidren.prototype.constructor=Chidren;//es6 类继承class Person{constructor(age,sex){this.age=age;this.sex=sex;}}class Chidren extends Person{constructor(age,sex,name,phone){super(age,sex);this.name=name;this.phone=phone;}}
class User {constructor(name) {this.name = name;}get name() {return this._name;}set name(value) {if (value.length < 4) {alert("Name is too short.");return;}this._name = value;}}let user = new User("John");alert(user.name); // Johnuser = new User(""); // Name is too short.
9. 对象方法扩展
export关键字标记了可以从当前模块外部访问的变量和函数。import关键字允许从其他模块导入功能。如果同一个模块被导入到多个其他位置,那么它的代码仅会在第一次导入时执行,然后将导出(export)的内容提供给所有的导入(importer)。
在实际开发中,顶级模块代码主要用于初始化,内部数据结构的创建,并且如果我们希望某些东西可以重用 — 请导出它。
!!!!type="module"的 js 里函数无法用 ```javascript
//static.js //分别暴露 export let school=’a’; export function b(){ console.log(“qqqq”); }
//统一暴露 let person = ‘ww’; function sex(){ console.log(“men”); } export {sex,person}; //默认暴露 数组 export default { school:’qqq’, change:function(){ console.log(“www”); } }
<a name="XzYhh"></a>## 11.解构函数```javascriptconst obj = {name: '1',age: 20,doing: {morning: '学习',afternoon: '学习',evening: 'sleep'}}const { name, age, gender } = objconsole.log(name, age, gender) // 1 22 男// 解构重名const { name: myname } = objconsole.log(myname) // 1// 嵌套解构const { doing: { evening } } = objconsole.log(evening) // sleep
ES7
xxx.includes()
传入元素,如果数组中能找到此元素,则返回true,否则返回false
const arr = [1, NaN]console.log(arr.indexOf(NaN)) // -1 indexOf找不到NaNconsole.log(arr.includes(NaN)) // true includes能找到NaN
2 **10 幂运算
ES8
async 和 await
Async/await 是以更舒适的方式使用 promise 的一种特殊语法
async
async 确保了函数返回一个 promise,也会将非 promise 的值包装进去。
await
- 关键字
await让 JavaScript 引擎等待直到 promise 完成(settle)并返回结果。 await只在async函数中有效。await返回promise成功的值await的promise失败了则会抛出异常,try{} catch(){}来捕获async/await的执行顺序
遇到await会阻塞后面的代码,先执行async外面的同步代码,同步代码执行完,再回到async内部,继续执行await后面的代码。以下面的代码分析:async/await的优缺点
- 优点
相对于promise,async/await处理 then 的调用链,代码要清晰很多,几乎和同步代码一样
2. 缺点
滥用 await 可能会导致性能问题,因为 await 会阻塞代码对象方法扩展
Object.values()获取对象所有的值
```javascript const school = { name:”aa”, cities:[‘吉林’,’河南’], xueke:[‘c’,’python’,’java’]Object.entries()获取遍历属性的数组
} a = Object.entries(school) console.log(a) const m = new Map(a) console.log(m)
<a name="VhYlG"></a>### `Object.getOwnPropertyDescriptors`对象属性的描述对象<a name="tNWGU"></a>## 函数<a name="V9VOr"></a>### `Padstart()` `PadEnd()` 填充字符串达到当前长度<a name="pY3fc"></a>## 函数参数列表结尾允许逗号<a name="LKbiD"></a># ES10 2019<a name="FsLBH"></a>### 1. Array的`arr.flat()` `arr.flatMap()`` flat(depth) //depth是指定要提取嵌套数组的结构深度,默认值为 1 ` 将所有元素与遍历到的子数组中的元素合并为一个新数组返回。```javascriptconst numbers1 = [1, 2, [3, 4, [5, 6]]]console.log(numbers1.flat())// [1, 2, 3, 4, [5, 6]]const numbers2 = [1, 2, [3, 4, [5, 6]]]console.log(numbers2.flat(2))// [1, 2, 3, 4, 5, 6]
flatMap() 是综合了map和flat的操作,所以它也只能打平一层
let arr = [1, 2, 3]console.log(arr.map(item => [item * 2]).flat()) // [2, 4, 6]console.log(arr.flatMap(item => [item * 2])) // [2, 4, 6]
2. Object的Object.fromEntries()
与 Object.entries 相反的操作
const object = { x: 23, y:24 };const entries = Object.entries(object); // [['x', 23], ['y', 24]]const result = Object.fromEntries(entries); // { x: 23, y: 24 }
3. String.trimStart() 和 String.trimEnd()
String.prototype.matchAll
4. BigInt
BigInt 只用来表示整数,没有位数的限制,任何位数的整数都可以精确表示。
const aNumber = 111;const aBigInt = BigInt(aNumber);aBigInt === 111n // truetypeof aBigInt === 'bigint' // truetypeof 111 // "number"typeof 111n // "bigint"
- Boolean
- Null
- Undefined
- Number
- String
- Symbol (new in ECMAScript 2015)
- BigInt (new in ECMAScript 2019)
5. Symbol.prototype.description
6. Function.prototype.toString()
之前执行这个方法时,得到的字符串是去空白符号的。而现在,得到的字符串呈现出原本源码的样子
ES11
1.Promise.allSettled
2.?. 和 ??
?.:中文名为可选链,不确定存不存在
而??和||最大的区别是,在??这,只有undefined和null才算假值
ES12
1. Promise.any
2. 数字分隔符
const num = 1000000000// 使用数字分隔符const num = 1_000_000_000
3.||= 和 &&=
或等于(||=) a ||= b等同于 a || (a = b);
且等于(&&=) a &&= b 等同于 a && (a = b);

