同系列文章请查看:Github:pre-interview
ES6(ES2015)
1.1 块级作用域
ES6之前没有块级作用域,ES5的var没有块级作用域的概念,只有function有作用域的概念,ES6的let、const引入了块级作用域。
ES5之前if和for都没有作用域,所以很多时候需要使用function的作用域,比如闭包。
1.1.1 什么是变量作用域
变量在什么范围内可用,类似Java的全局变量和局部变量的概念,全局变量,全局都可用,局部变量只在范围内可用。ES5之前的var是没有块级作用域的概念,使用var声明的变量就是全局的。
1 | { |
上述代码中{}外的console.log(name)
可以获取到name值并打印出来,用var声明赋值的变量是全局变量,没有块级作用域。
1.1.2 没有块级作用域造成的问题
if块级
1 | var func; |
代码输出结果为'zzz','ttt','ttt'
,第一次调用func(),此时name=‘zzz’,在if块外将name置成‘ttt’,此时生效了,if没有块级作用域。
for块级
定义五个按钮,增加事件,点击哪个按钮打印“第哪个按钮被点击了”。
1 |
|
for块级中使用var
声明变量i时,是全局变量,点击任意按钮结果都是“第五个按钮被点击了”。
即每一次看似在for块级里面声明的 i ,其实都是全局作用域的 i ,循环到最后一次,前面的i被覆盖,于是全局作用域 i=5 ,不管点击任何按钮都是最后一个。
说明在执行btns[i].addEventListener('click',function())
时,for块级循环已经走完,此时i=5
,所有添加的事件的i都是5。
改造上述代码,将for循环改造,由于函数有作用域,使用闭包能解决上述问题。
1 | // 使用闭包,函数有作用域 |
结果如图所示,借用函数的作用域解决块级作用域的问题,因为有块级作用域,每次添加的i都是当前i。
在ES6中使用let/const解决块级作用域问题,let和const有块级作用域,const定义常量,在for块级中使用let解决块级作用域问题。
1 | // ES6使用let/const |
结果和使用闭包解决一致。
1.2 const的使用
- const用来定义常量,赋值后不能再赋值,再次赋值会报错。
1 | <script> |
- const不能只声明不赋值,会报错。
1 | <script> |
- const常量含义是你不能改变其指向的对象,例如user,但是你可以改变user(对象内部的)属性。
1 | <script> |
- const内存地址详解
对象count一开始只想0x10的地址,直接将count(给count重新赋值,指向一个新的对象)指向地址改为0x20会报错,const是常量,无法更改对象地址。
对象user一开始指向0x10地址,user有Name
、Age
、Height
三个属性,此时修改属性Name='ttt'
,user对象的地址未改变,不会报错。
1.3 ES6的增强写法
1.3.1 ES6的对象属性增强型写法
- ES6以前定义一个对象
1 | const name = "zzz"; |
- ES6写法
1 | const name = "zzz"; |
1.3.2 ES6对象的函数增强型写法
- ES6之前对象内定义函数
1 | const obj = { |
- ES6写法
1 | const obj = { |
1.4 箭头函数
1.4.1 认识箭头函数
传统定义函数的方式
1 | const aaa = function (param) { |
对象字面量中定义函数
1 | const obj = { |
ES6中的箭头函数
1 | //const ccc = (参数列表) => {} |
1.4.2 箭头函数的参数和返回值
参数问题
1.放入两个参数
1 | const sum = (num1,num2) => { |
2.放入一个参数,()可以省略
1 | const power = num => { |
函数内部
1.函数中代码块中有多行代码
1 | const test = () =>{ |
2.函数代码块中只有一行代码,可以省略return
1 | // const mul = (num1,num2) => { |
1.4.3 箭头函数的this使用
什么时候使用箭头函数
- 当把一个函数作为参数传入另外一个函数时使用
1 | setTimeout(function () { |
结论:箭头函数没有this,这里this引用的是最近作用域(aaa函数里的this)的this。
1 | const obj = { |
上述中第一个是window对象的this,第二个箭头函数的this是obj的。
1 | const obj = { |
1.5 高阶函数
1.5.1 filter过滤函数
-
只能用来过滤,不能处理元素。
-
返回值:true/false,返回原数组里的元素
1 | const nums = [2,3,5,1,77,55,100,200] |
1.5.2 map高阶函数
-
可以对元素进行处理
-
返回值:回调的return
1 | // 要求将已经过滤的新数组每项乘以2 |
1.5.3 reduce高阶函数
- 对数组元素汇总
- 参数
- 回调函数
- preValue:初始值,0
- item:遍历数组元素值
- 0
- 回调函数
1 | // 3.reduce高阶函数 |
1.5.4 综合使用
1 | //三个需求综合 |
1.6 Promise
详见 《13_Promise》
ES7
1 | 1.Array.prototype.includes() |
ES8
async/await
异步终极解决方案
1 | async getData(){ |
Object.values()
1 | Object.values({a: 1, b: 2, c: 3}); // [1, 2, 3] |
Object.entries()
1 | Object.entries({a: 1, b: 2, c: 3}); // [["a", 1], ["b", 2], ["c", 3]] |
String padding
1 | // padStart |
函数参数列表结尾允许逗号
Object.getOwnPropertyDescriptors()
获取一个对象的所有自身属性的描述符,如果没有任何自身属性,则返回空对象。
SharedArrayBuffer对象
SharedArrayBuffer 对象用来表示一个通用的,固定长度的原始二进制数据缓冲区
1 | /** |
Atomics对象
Atomics 对象提供了一组静态方法用来对 SharedArrayBuffer 对象进行原子操作。
ES9
异步迭代
await可以和for…of循环一起使用,以串行的方式运行异步操作
1 | async function process(array) { |
Promise.finally()
1 | Promise.resolve().then().catch(e => e).finally(); |
Rest/Spread 属性
1 | const values = [1, 2, 3, 5, 6]; |
正则表达式命名捕获组
1 | const reg = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})/; |
正则表达式反向断言
1 | (?=p)、(?<=p) p 前面(位置)、p 后面(位置) |
正则表达式dotAll模式
正则表达式中点.匹配除回车外的任何单字符,标记s改变这种行为,允许行终止符的出现
1 | /hello.world/.test('hello\nworld'); // false |
ES10
Array.flat()和Array.flatMap()
1 | // flat() |
String.trimStart()和String.trimEnd()
去除字符串首尾空白字符
String.prototype.matchAll
matchAll()为所有匹配的匹配对象返回一个迭代器
1 | const raw_arr = 'test1 test2 test3'.matchAll((/t(e)(st(\d?))/g)); |
结果:
Symbol.prototype.description
只读属性,回 Symbol 对象的可选描述的字符串。
1 | Symbol('description').description; // 'description' |
Object.fromEntries()
返回一个给定对象自身可枚举属性的键值对数组
1 | // 通过 Object.fromEntries, 可以将 Map 转化为 Object: |
可选 Catch
ES11
Nullish coalescing Operator(空值处理)
表达式在 ?? 的左侧 运算符求值为undefined或null,返回其右侧。
1 | let user = { |
Optional chaining(可选链)
?.用户检测不确定的中间节点
1 | let user = {} |
Promise.allSettled
返回一个在所有给定的promise已被决议或被拒绝后决议的promise,并带有一个对象数组,每个对象表示对应的promise结果.
1 | const promise1 = Promise.resolve(3); |
结果:
import()
按需导入
新基本数据类型BigInt
任意精度的整数
globalThis
浏览器:window
worker:self
node:global
ES12(2021)
replaceAll
返回一个全新的字符串,所有符合匹配规则的字符都将被替换掉
1 | const str = 'hello world'; |
Promise.any
1 | Promise.any() 接收一个Promise可迭代对象,只要其中的一个 promise 成功,就返回那个已经成功的 promise 。如果可迭代对象中没有一个 promise 成功(即所有的 promises 都失败/拒绝),就返回一个失败的 promise |
结果:
WeakRefs
使用WeakRefs的Class类创建对对象的弱引用(对对象的弱引用是指当该对象应该被GC回收时不会阻止GC的回收行为)
逻辑运算符和赋值表达式
逻辑运算符和赋值表达式,新特性结合了逻辑运算符(&&,||,??)和赋值表达式而JavaScript已存在的 复合赋值运算符有:
1 | a ||= b |
Tips: Please indicate the source and original author when reprinting or quoting this article.