1. ES6 的新特性有哪些?
- let 和 const 声明: 引入块级作用域的变量声明方式,let 声明的变量可重新赋值,const 声明的变量不可重新赋值。
- 箭头函数(Arrow Functions): 提供了更简洁的函数定义语法,并且没有自己的 this、arguments、super 或 new.target,这些值继承自执行上下文。
- 模板字符串(Template Strings): 使用反引号 ` 定义字符串,支持多行字符串和插值表达式 ${}。
- 解构赋值(Destructuring Assignment): 可以方便地从数组或对象中提取值并赋给变量。
- 对象字面量扩展(Object Literal Enhancements): 提供了更简洁的语法来定义对象属性和方法,支持简写、计算属性名等。
- 类和继承(Classes and Inheritance): 引入了类的概念,更接近传统面向对象语言的语法,支持类的继承和构造函数。
- 模块化(Modules): 提供了原生的模块化支持,使用 import 和 export 关键字来导入和导出模块。
- 默认参数(Default Parameters): 允许在函数定义时为参数设置默认值,简化函数的使用。
- 展开运算符(Spread Operator): 允许在函数调用、数组字面量和对象字面量中展开数组和对象。
- 剩余参数(Rest Parameters): 允许将不定数量的参数表示为一个数组,简化函数参数的处理。
- Symbol 类型(Symbol): 引入了一种新的基本数据类型,表示独一无二的值,用于创建对象的唯一属性名。
- 迭代器和生成器(Iterators and Generators): 提供了用于迭代数据结构的统一接口,并且引入了生成器函数语法,使得迭代更加简单和灵活。
- Promise 对象(Promises): 提供了一种更加灵活和强大的异步编程解决方案,使得处理异步操作更加优雅。
- Map 和 Set 数据结构: 提供了更方便和高效的数据结构,用于存储键值对和集合,替代了传统的对象和数组。
- Proxy 和 Reflect 对象: 提供了元编程的能力,允许你创建一个对象的代理,拦截并修改其底层的默认行为。
2. let、const、var 三者的区别?
let/const 是es6新增的变量声明命令,与var不同的是,let/const声明的变量不会做变量提升,变量在声明之前,存在暂时性死区,不可引用,否则会报错。相对的var声明的变量,在声明之前引用则是返回undefined。
let用于声明变量,const则用于声明常量,即const仅在声明之时赋值,声明之后不可重新赋值。
3. Set和Map各是什么?
Set是一种集合数据结构,存储一组唯一的值,而Map则是一种键值对的集合,其中的每个键都是唯一的。
Set的值的顺序为插入的顺序,不会改变,且不允许有重复的值。
Map的键可以是任意类型的值,包括基本类型、对象、甚至函数。可以通过键来获取值。
4. 箭头函数和普通函数之间有什么区别?
- 语法:
- 箭头函数使用箭头 (=>) 符号来定义,语法更加简洁明了。
- 普通函数使用关键字 function 来定义,语法相对更为繁琐。
- this 的绑定:
- 箭头函数没有自己的 this 绑定,它的 this 是词法上的,指向定义时所在的上下文(外层作用域)的 this 值,这意味着箭头函数中的 this 指向不能被改变。
- 普通函数的 this 是在运行时动态绑定的,根据函数的调用方式和执行上下文不同而不同。
- arguments 对象:
- 箭头函数没有自己的 arguments 对象,它的 arguments 变量继承自外层作用域,指向最近一层函数的 arguments 对象(如果有的话)。
- 普通函数有自己的 arguments 对象,可以访问到函数内部的参数。
- new 关键字:
- 箭头函数不能被用作构造函数,不能通过 new 关键字调用。
- 普通函数可以通过 new 关键字调用,并且可以作为构造函数使用。
- prototype 属性:
- 箭头函数没有 prototype 属性,因为它不能被用作构造函数。
- 普通函数有 prototype 属性,可以被用作构造函数,用于创建实例对象。
5. Promise
Promise 是一种用于处理异步操作的对象,有三种状态:pending、fulfilled、rejected,分别表示进行中、已完成、已失败。
6. Promise 和 async/await
- 语法差异:
- Promise 是一种基于回调函数的异步编程模式,通过链式调用 then 方法或 catch 方法来处理异步操作的结果或错误。
- async/await 是基于 Promise 的语法糖,它提供了一种更清晰、更简洁的异步编程方式,通过在函数定义前加上 async 关键字标识异步函数,在异步操作前使用 await 关键字等待结果。
- 代码可读性:
- async/await 的语法更加直观清晰,可以更容易地理解和维护异步代码,避免了回调地狱(callback hell)的问题。
- Promise 虽然也可以使用链式调用来处理异步操作,但是当异步操作较多时,可能会导致代码嵌套层级过深,影响代码可读性。
- 错误处理:
- Promise 可以通过链式调用的方式使用 catch 方法来捕获异步操作中的错误,并进行统一处理。
- async/await 则可以使用 try...catch 语句来捕获异步操作中的错误,使得错误处理更加灵活和方便。
- 性能:
- 在某些情况下,async/await 可能会稍微慢一些,因为它是基于 Promise 实现的,并且在内部会进行一些额外的转换和处理。
- 但在大多数情况下,async/await 的性能损耗可以忽略不计,并且由于其代码更加清晰和易读,可以减少错误和提高开发效率。