es6面试题总结最全

本文详细总结了ES6中的核心面试知识点,包括var、let、const的区别,数组、对象的扩展,Set和Map数据结构,Promise、Generator、Proxy、Module的理解及使用场景,以及Decorator的原理与应用。通过这些内容,有助于全面理解和掌握ES6的特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

说一下var、let、const之间的区别?

var:

var声明的变量既是全局变量,也是顶层变量(顶层对象,在浏览器环境下指的是window对象,在node中指的是global对象)

var存在变量提升,可以对一个变量进行多次声明,后面声明的变量会覆盖前面的变量声明

在函数中使用var声明变量,变量是局部的,如果在函数内不使用var,那么这个变量就是全局的

let:

let是es6新增的命令,用来声明变量,他和var类似,但是let只在代码块中有效

不存在变量提升,不允许重复声明变量

let存在暂时性死区,是个块级作用域,

只要在let块级作用域内存在let命令,这个区域就不会受外部影响

在使用let声明变量之前,该变量都不可用,也就是我们常说的暂时性死区

const:

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

const 一旦声明变量,必须立即初始化,不能留到以后赋值

const实际上保证的并不是变量的值不能改动,而是变量指向的内存地址所保存的数据不能改动

对于简单类型的数据,值就保存在变量指向的那个内存地址,因此等同于常量

区别:

可以根据以下5点展开

变量提升:var存在变量提升,let和const不存在变量提升

暂时性死区:var不存在暂时性死区,let和const存在暂时性死区

块级作用域:var不存在块级作用域,let和const存在块级作用域

修改声明的变量:var允许重复声明变量,let和const一律不允许重复声明变量

使用:能使用const尽量使用const,其他情况使用let,避免使用var

es6中数组新增了哪些扩展?

扩展运算符: (...)好比rest参数的逆运算,将一个数组转化为用逗号分隔的参数序列

可以实现简单的数组复制,数组的合并也更加简洁

通过扩展运算符实现浅拷贝,修改了引用指向的值,会同步反映到新的数组

构造函数新增的方法:

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

Array.of() 用于将一组值,转换为数组,没有参数时,返回一个空数组,当参数有一个时,是指定数组的长度

实例对象新增的方法:

copyWithin()将指定位置的成员复制到其他位置(会覆盖原有成员)

  • target(必需):从该位置开始替换数据。如果为负值,表示倒数。
  • start(可选):从该位置开始读取数据,默认为 0。如果为负值,表示从末尾开始计算。
  • end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示从末尾开始计算

find()、findIndex() 用于找出第一个符合条件的数组成员,参数是一个回调函数,接受三个参数依次为当前的值、当前的位置和原数组

fill():使用给定值,填充一个数组

        三个参数:分别是填充的值,填充的开始位置,填充的结束位置

entries(),keys(),values():keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历

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

        方法的第二个参数表示搜索的起始位置,默认为0

        参数为负数则表示倒数的位置

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

flat()默认只会“拉平”一层,如果想要“拉平”多层的嵌套数组,可以将flat()方法的参数写成一个整数,表示想要拉平的层数,默认为1

flatMap()方法对原数组的每个成员执行一个函数相当于执行Array.prototype.map(),然后对返回值组成的数组执行flat()方法。该方法返回一个新数组,不改变原数组

flatMap()方法还可以有第二个参数,用来绑定遍历函数里面的this

数组的空位

空位指的是某一个位置没有任何值

ES6 则是明确将空位转为undefined,包括Array.from、扩展运算符、copyWithin()fill()entries()keys()values()find()findIndex()

建议大家在日常书写中,避免出现空位

 对象新增了哪些扩展?

属性的简写:

当我们键名和对应值名相等时,可以进行简写,方法也可以进行简写

注意:简写的对象方法不能用作构造函数,否则会报错

属性名表达式

es6允许字面量定义对象,将表达式放在括号中,表达式还可以用于定义方法名

super关键字

this关键字总是指向函数所在的当前对象,super关键字指向当前对象的原型对象

扩展运算符 

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

解构赋值必须是最后一个参数,否则会报错

解构赋值是浅拷贝

属性遍历

es6一共有5种方法遍历对象的属性

  • for...in:循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)

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

  • Object.getOwnPropertyNames(obj):回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名

  • Object.getOwnPropertySymbols(obj):返回一个数组,包含对象自身的所有 Symbol 属性的键名

  • Reflect.ownKeys(obj):返回一个数组,包含对象自身的(不含继承的)所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举

对象新增的方法:

Object.is()

严格判断两个值是否相等,与严格比较运算符(===)的行为基本一致,不同之处只有两个:一是+0不等于-0,二是NaN等于自身

Object.assign()

Object.assign()方法用于对象的合并,将源对象source的所有可枚举属性,复制到目标对象target

Object.assign()方法的第一个参数是目标对象,后面的参数都是源对象

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

Object.getOwnPropertyDescriptors()

返回指定对象所有自身属性(非继承属性)的描述对象

Object.setPrototypeOf(),方法用来设置一个对象的原型对象

Object.getPrototypeOf()用于读取一个对象的原型对象

Object.keys(),返回自身的(不含继承的)所有可遍历(enumerable)属性的键名的数组

Object.values(),返回自身的(不含继承的)所有可遍历(enumerable)属性的键对应值的数组

Object.entries():返回一个对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对的数组

Object.fromEntries():用于将一个键值对数组转为对象

对象新增了哪些扩展?

参数

ES6允许为函数的参数设置默认值,函数的形参是默认声明的,不能使用let或const再次声明

参数的默认值可以与解构赋值的默认值结合起来使用

属性

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

如果设置了默认值的参数不是尾参数,那么length属性也不会再计入后面的参数

name:返回函数的函数名

作用域

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

等初始化结束之后,这个作用域也会消失

严格模式

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

箭头函数 

=>定义函数,如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分

 如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回

注意点:

  • 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象
  • 不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误
  • 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替
  • 不可以使用yield命令,因此箭头函数不能用作 Generator 函数

 谈谈你对es6中新增的set,map两种数据结构的理解?

 set时一种叫做集合的数据结构,map是一种叫做字典的数据结构

集合:由一堆无序的相关联的,且不重复的内部结构组成的组合

字典:是一些元素的集合。每个元素有一个称作key 的域,不同元素的key 各不相同

区别?

  • 共同点:集合、字典都可以存储不重复的值
  • 不同点:集合是以[值,值]的形式存储元素,字典是以[键,值]的形式存储

set:

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

set本身是一个构造函数,用来生成set数据结构

增删改查

  • add()添加某个值,返回 Set 结构本身

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

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

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

 遍历

  • keys():返回键名的遍历器
  • values():返回键值的遍历器
  • entries():返回键值对的遍历器
  • forEach():使用回调函数遍历每个成员

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

map

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

map本身是一个构造函数,用来生成map数据结构

增删改查

  • size 属性返回 Map 结构的成员总数
  • set()设置键名key对应的键值为value,然后返回整个 Map 结构

    如果key已经有值,则键值会被更新,否则就新生成该键

    同时返回的是当前Map对象,可采用链式写法

  • get()get方法读取key对应的键值,如果找不到key,返回undefined
  • has()has方法返回一个布尔值,表示某个键是否在当前 Map 对象之中
  • delete()delete方法删除某个键,返回true。如果删除失败,返回false
  • clear()clear方法清除所有成员,没有返回值

遍历

  • eys():返回键名的遍历器
  • values():返回键值的遍历器
  • entries():返回所有成员的遍历器
  • forEach():遍历 Map 的所有成员

你是怎么理解es6中的promise?

promise(承诺),他是异步编程的一种解决方案,比传统的解决方案更加合理和更加强大

promise解决异步操作的优点:

链式操作降低了编码难度

代码的可读性明显增强

状态:

 promise有三种状态

pending:进行中

fulfilled:已成功

rejected:已失败

特点:

  • 对象的状态不受外界影响,只有异步操作的结果,可以决定当前是哪一种状态
  • 一旦状态改变(从pending变为fulfilled和从pending变为rejected),就不会再变,任何时候都可以得到这个结果

流程

 

用法

 promise对象是一个构造函数,用来生成promise实例,promise构造函数接收一个函数作为参数,该函数的两个参数分别是resolve和reject

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

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

实例方法

then

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

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

catch

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

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

finally

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

all

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

race

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

使用场景

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

你是怎么理解ES6中 Generator的?使用场景?

Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同

回顾下上文提到的解决异步的手段:

  • 回调函数
  • promise

Generator函数

执行 Generator 函数会返回一个遍历器对象,可以依次遍历 Generator 函数内部的每一个状态

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

  • function关键字与函数名之间有一个星号
  • 函数体内部使用yield表达式,定义不同的内部状态

使用

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

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

异步解决的方案

回调函数:回调函数,就是把任务代码单独写在一个函数里,等到重新执行这个任务时,再调用这个函数

Promise 对象:就是为了解决回调地狱而产生的

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

async/await:代码更加简介,语义化更强

区别?

  • promiseasync/await是专门用于处理异步操作的

  • Generator并不是为异步而设计出来的,它还有其他功能(对象迭代、控制输出、部署Interator接口...)

  • promise编写代码相比Generatorasync更为复杂化,且可读性也稍差

  • Generatorasync需要与promise对象搭配处理异步情况

  • async实质是Generator的语法糖,相当于会自动执行Generator函数

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

使用场景

Generator是异步解决的一种方案,最大特点则是将异步操作同步化表达出来

你是怎么理解ES6中Proxy的?使用场景?

用来定义基本操作中的自定义行为

本质就是修改程序的默认行为,形同与在编程语言层面上做一些修改,属于元编程

元编程(Metaprogramming,又译超编程,是指某类计算机程序的编写,这类计算机程序编写或者操纵其它程序(或者自身)作为它们的数据,或者在运行时完成部分本应在编译时完成的工作

元编程的特点:与手工编写全部代码相比,程序员可以获得更高的工作效率,或者给与程序更大的灵活度去处理新的情形而无需重新编译

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

用法:

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

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

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

var proxy = new Proxy(target, handler)

取消代理

Proxy.revocable(target, handler);

使用场景

  • 拦截和监视外部对对象的访问
  • 降低函数或类的复杂度
  • 在复杂操作前对操作进行校验或对所需资源进行管理

你是怎么理解ES6中Module的?使用场景?

模块,是能够单独命名并独立的完成一定功能的程序语句的集合(程序代码和数据结构的集合体)

两个基本的特征:外部特征和内部特征

  • 外部特征是指模块跟外部环境联系的接口(即其他模块或程序调用该模块的方式,包括有输入输出参数、引用的全局变量)和模块的功能

  • 内部特征是指模块的内部环境具有的特点(即该模块的局部数据和程序代码)

为什么需要模块化?

  • 代码抽象
  • 代码封装
  • 代码复用
  • 依赖管理

如果我们没有模块化,我们的代码会变得不容易维护,容易污染全局作用域

加载资源的方式通过script标签从上到下

依赖的环境主观逻辑偏重,代码较多就会比较复杂

大型项目资源难以维护,特别是多人合作的情况下,资源会让人崩溃

使用

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

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

        一个模块就是一个独立的文件,该文件内部的所有变量,外部无法获取,如果希望外部能够读取内部的某个变量,就必须通过export关键字输出该变量

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

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

我们可以通过as 关键字配置别名

当我们需要加载整个模块,使用*

输入的变量都是只读的,不允许修改,但是如果是对象,允许修改属性

动态加载

允许仅在需要时动态加载模块,不必预先加载所有模块,性能优势明显

这个功能允许我们将import作为函数调用,将其作为参数传递给模块的路径

使用场景

 如今,ES6模块化已经深入我们日常项目开发中,像vuereact项目搭建项目,组件化开发处处可见,其也是依赖模块化实现

你是怎么理解ES6中 Decorator 的?使用场景?

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

本质也是一个普通的函数,用于扩展类属性和类方法

用法:

类的装饰:对类本身进行装饰,能够接收一个参数

类属性的装饰:

  • 类的原型对象
  • 需要装饰的属性名
  • 装饰属性名的描述对象

首先定义yigereadonly装饰器,使用readonly装饰类的name方法,如果一个方法有对各装饰器,就像洋葱一样,从外到内,再由内到外执行

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值