ES6面试题整理汇总

1、面试官:说说var、let、const之间的区别

ES6之前创建变量用的是var,之后创建变量用的是let/const

var、let、const三者区别可以围绕下面五点展开:

1、变量提升

var声明的变量存在变量提升,即变量可以在声明之前调用,值为undefined

let和const不存在变量提升,即它们所声明的变量一定要在声明后使用,否则报错

2、暂时性死区

var不存在暂时性死区。let和const存在暂时性死区,只有等到声明变量的那一行代码出现,才可以获取和使用该变量

3、块级作用域

var不存在块级作用域

let和const存在块级作用域

4、重复声明

var允许重复声明变量

let和const在同一作用域不允许重复声明变量

5、修改声明的变量

var和let可以

const声明一个只读的常量。一旦声明,常量的值就不能改变

6、使用

能用const的情况尽量使用const,其他情况下大多数使用let,避免使用var

2、面试官:ES6中数组新增了哪些扩展?

一、扩展运算符的应用

ES6通过扩展元素符...,将一个数组转为用逗号分隔的参数序列

console.log(...[1,2, 3])      // 1 2 3

扩展运算符可以与解构赋值结合起来,用于生成数组

const[first, ...rest] = [1, 2, 3, 4, 5];
first   // 1        rest   // [2, 3, 4, 5]

二、构造函数新增的方法

1、Array.from()

将两类对象转为真正的数组:类似数组的对象和可遍历(iterable)的对象

arrayLike为类似数组的对象

letarr2 = Array.from(arrayLike);       //['a', 'b', 'c']

2、Array.of()

用于将一组值,转换为数组

Array.of(3,11, 8)                   // [3,11,8]

三、实例对象新增的方法

1、copyWithin():将指定位置的成员复制到其他位置(会覆盖原有成员),返回当前数组

2、find()用于找出第一个符合条件的数组成员

3、includes() :用于判断数组是否包含给定的值

  1. flat() :将数组扁平化处理,返回一个新数组,对原数据没有影响

[1,2, [3, 4]].flat()        // [1, 2, 3, 4]

四、数组的空位

数组的空位指,数组的某一个位置没有任何值,ES6 则是明确将空位转为undefined

五、排序稳定性

将sort()默认设置为稳定的排序算法

3、面试官:ES6中对象新增了哪些扩展?

一、属性的简写

ES6中,当对象键名与对应值名相等的时候,可以进行简写,方法也能够进行简写

二、属性名表达式

ES6允许字面量定义对象时,将表达式放在括号内

let lastWord = 'last word';
consta = {
  'first word': 'hello',
  [lastWord]: 'world'
};

a['first word'] // "hello"
a[lastWord] // "world"
a['last word'] // "world"

三、super关键字

this关键字总是指向函数所在的当前对象,ES6 又新增了另一个类似的关键字super,指向当前对象的原型对象

四、扩展运算符的应用

在解构赋值中,未被读取的可遍历的属性,分配到指定的对象上面

let{ x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x// 1    y // 2    z // { a: 3, b: 4 }

五、属性的遍历

for...in:循环遍历对象自身的和继承的可枚举属性

Object.keys(obj):返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名

六、对象新增的方法

Object.is() :严格判断两个值是否相等

一是+0不等于-0,二是NaN等于自身

Object.assign()

Object.assign()方法用于对象的合并, target, source1, source2都为对象

Object.assign(target,source1, source2);

注意:Object.assign()方法是浅拷贝,遇到同名属性会进行替换

4、面试官:ES6中函数新增了哪些扩展?

一、参数

ES6允许为函数的参数设置默认值

函数的形参是默认声明的,不能使用let或const再次声明

二、属性

函数的length属性:length将返回没有指定默认值的参数个数

name属性:返回该函数的函数名

三、作用域

一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域

四、严格模式

只要函数参数使用了默认值、解构赋值、或者扩展运算符,那么函数内部就不能显式设定为严格模式,否则会报错

五、箭头函数

使用“箭头”(=>)定义函数

函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象

5、面试官:你是怎么理解ES6新增Set、Map两种数据结构的?

一、Set

Set是一种叫做集合的数据结构,Map是一种叫做字典的数据结构

Set是es6新增的数据结构,类似于数组,但是成员的值都是唯一的,没有重复的值,我们一般称为集合

Set的实例关于增删改查的方法:

add() :添加某个值,返回 Set 结构本身,当添加实例中已经存在的元素,set不会进行处理添加

delete():删除某个值,返回一个布尔值,表示删除是否成功

has():返回一个布尔值,判断该值是否为Set的成员

clear():清除所有成员,没有返回值

Set实例遍历的方法有如下:

1、keys():返回键名的遍历器

2、values():返回键值的遍历器

3、entries():返回键值对的遍历器

4、forEach():使用回调函数遍历每个成员

扩展运算符和Set 结构相结合实现数组或字符串去重

letarr = [3, 5, 2, 2, 5, 5];

letunique = [...new Set(arr)]; // [3, 5, 2]

二、Map

Map类型是键值对的有序列表,而键和值都可以是任意类型

Map结构的实例针对增删改查有以下属性和操作方法:

size属性:size属性返回 Map 结构的成员总数。

set():设置键名key对应的键值为value,然后返回整个 Map 结构

get():get方法读取key对应的键值,如果找不到key,返回undefined

has():has方法返回一个布尔值,表示某个键是否在当前 Map 对象之中

delete():delete方法删除某个键,返回true。如果删除失败,返回false

clear():clear方法清除所有成员,没有返回值

Map结构原生提供三个遍历器生成函数和一个遍历方法:

keys():返回键名的遍历器

values():返回键值的遍历器

entries():返回所有成员的遍历器

forEach():遍历 Map 的所有成员

6、面试官:你是怎么理解ES6中Generator的?使用场景?

Generator函数是一个普通函数,但是有两个特征:

1、function关键字与函数名之间有一个星号

2、函数体内部使用yield表达式,定义不同的内部状态

function*helloWorldGenerator() {
  yield 'hello';
  yield 'world';
  return 'ending';
}
var hw  =  helloWorldGenerator();

Generator函数会返回一个遍历器对象,即具有Symbol.iterator属性,并且返回给自己

通过yield关键字可以暂停generator函数返回的遍历器对象的状态

通过next方法才会遍历到下一个内部状态

hw.next()    // { value: 'hello', done: false }
hw.next()    // { value: 'world', done: false }
hw.next()    // { value: 'ending', done: true }
hw.next()    // { value: undefined, done: true }

正因为Generator函数返回Iterator对象,因此我们还可以通过for...of进行遍历

异步解决方案

yield表达式可以暂停函数执行,next方法用于恢复函数执行,这使得Generator函数非常适合将异步任务同步化

async/await

async函数返回一个 Promise 对象,当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再执行函数体内后面的语句。可以理解为,是让出了线程,跳出了 async 函数体。async实质是Generator的语法糖,相当于会自动执行Generator函数

async使用上更为简洁,将异步代码以同步的形式进行编写,是处理异步编程的最终方案

7、面试官:你是怎么理解ES6中Promise的?使用场景?

Promise是异步编程的一种解决方案,解决回调地狱的问题

promise解决异步操作的优点:

1、链式操作减低了编码难度 2、代码可读性明显增强

promise对象仅有三种状态

1、pending(进行中)2、fulfilled(已成功)3、rejected(已失败)

Promise对象是一个构造函数,用来生成Promise实例

constpromise = new Promise(function(resolve, reject) {} );

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject

resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”

reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”

Promise构建出来的实例存在以下方法:

1、then() 2、catch() 3、finally()

then是实例状态发生改变时的回调函数,第一个参数是resolved状态的回调函数,第二个参数是rejected状态的回调函数

then方法返回的是一个新的Promise实例,也就是promise能链式书写的原因

catch()方法是.then(null, rejection)或.then(undefined, rejection)的别名,用于指定发生错误时的回调函数

Promise对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止

finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作

Promise构造函数存在以下方法:

1、Promise.all()方法用于将多个 Promise实例,包装成一个新的 Promise实例

2、Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例

3、resolve()将现有对象转为 Promise对象

4、Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected

三、使用场景

将图片的加载写成一个Promise,一旦加载完成,Promise的状态就发生变化

8、面试官:你是怎么理解ES6中Proxy的?使用场景?

Proxy用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)

Proxy为构造函数,用来生成 Proxy实例

varproxy = new Proxy(target, handler)

target表示所要拦截的目标对象(任何类型的对象,包括原生数组,函数,甚至另一个代理))

handler通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 p 的行为

关于handler拦截属性,有如下:(暂时背三个)

1、get(target,propKey,receiver):拦截对象属性的读取

2、set(target,propKey,value,receiver):拦截对象属性的设置

3、has(target,propKey):拦截propKey in proxy的操作,返回一个布尔值

9、面试官:你是怎么理解ES6中Module的?使用场景?

模块(Module),是能够单独命名并独立地完成一定功能的程序语句的集合

模块化的作用能够将代码抽象、代码封装、代码复用以及依赖管理

将JavaScript程序模块化的机制,如

1、CommonJs 2、AMD (典型代表:require.js) 3、CMD

模块功能主要由两个命令构成:

1、export:用于规定模块的对外接口

2、import:用于输入其他模块提供的功能

暴露又分为分别暴露、统一暴露以及默认暴露

使用export命令定义了模块的对外接口以后,其他 JS 文件就可以通过import命令加载这个模块

使用场景

1、vue组件2、react组件

包括完成一些复杂应用的时候,我们也可以拆分成各个模块

10、面试官:你是怎么理解ES6中Decorator 的?使用场景?

Decorator,即装饰器,装饰者模式就是一种在不改变原类和使用继承的情况下,动态地扩展对象功能的设计理论

Decorator两大优点:

1、代码可读性变强了,装饰器命名相当于一个注释

2、在不改变原有代码情况下,对原来功能进行扩展

Docorator修饰对象为下面两种:

1、类的装饰

2、类属性的装饰

注意

装饰器不能用于修饰函数,因为函数存在变量声明情况

几个常见的装饰器

@antobind:autobind装饰器使得方法中的this对象,绑定原始对象

@readonly:readonly装饰器使得属性或方法不可写

@deprecate:deprecate或deprecated装饰器在控制台显示一条警告,表示该方法将废除

猜你喜欢

转载自blog.csdn.net/weixin_55608297/article/details/129770935