狐七的面试题库

整理,永远在路上~

ES6

3/21/2022 js

# 1. ES6 代码转成 ES5 代码的实现思路?

查看答案

ES6 转 ES5 目前行业标配是用 Babel,转换的大致流程如下:

  1. 解析:解析代码字符串,生成 AST
  2. 转换:按一定的规则转换、修改 AST
  3. 生成:将修改后的 AST 转换成普通代码

如果不用工具,纯人工的话,就是使用或自己写各种 polyfill。

# 2. var、let 和 const 的区别

查看答案

三者的区别:

  • var 和 let 用以声明变量,const 用于声明只读的常量。
  • var 声明的变量,不存在块级作用域,在全局范围内都有效;let 和 const 声明的,只在它所在的代码块内有效,不会挂载到window全局对象上。
  • let 和 const 不存在像 var 那样的 “变量提升” 现象,所以 var 定义变量可以先使用,后声明,而 let 和 const 只可先声明,后使用。
  • let、const声明的变量存在暂时性死区(TDZ),即只要块级作用域中存在let和const,那么它所声明的变量就绑定了这个区域,不再受外部的影响。
  • let、const不允许在相同作用域内,重复声明同一个变量。
  • const在声明时必须初始化赋值,一旦赋值,值就不允许改变。
  • const 声明了一个复合类型的常量,其存储的是一个引用地址,不允许改变的是这个地址,而对象本身是可变的。

# 3. const赋值之后不能修改的原理是什么?

查看答案

变量与内存之间的关系,主要由三个部分组成:

  • 变量名
  • 内存地址
  • 内存空间

JS引擎在读取变量时,先找到变量绑定的内存地址,然后找到地址所指向的内存空间,最后读取其中的内容。

当变量改变时,JS引擎不会用新值覆盖之前旧值的内存空间(虽然从写代码的角度来看,确实像是被覆盖掉了)。
而是:

  1. 重新分配一个新的内存空间来存储新值
  2. 将新的内存地址与变量进行绑定
  3. JS引擎会在合适的时机进行GC,回收旧的内存空间。

const定义变量(常量)后,变量名与内存地址之间建立了一种不可变的绑定关系,阻隔变量地址被改变。
当 const 定义的变量进行重新赋值时,根据前面的论述,JS引擎会尝试重新分配新的内存空间,所以会被拒绝,便会抛出异常。

# 4. 全局作用域中,用 const 和 let 声明的变量不在 window 上,那在哪里获取?

查看答案
  • var和function声明的全局变量,依旧是顶层对象的属性,使用的时候可以用window.变量获取。
  • let、const、class声明的全局变量,不属于顶层对象的属性,只是一个块级作用域(Script)中,使用的时候在块级作用域中就可以获取,不加window。

# 5. 什么时候回出现暂时性死区(TDZ)

查看答案
  1. 声明let、const之前
  2. 函数参数赋值默认值之前,默认值为undefined

# 6. Set、Map、WeakSet 和 WeakMap 的区别?

查看答案
  • Set
    • 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用
  • WeakSet
    • 成员都是对象,成员都是弱引用
    • 可以被垃圾回收机制回收
    • 可以用来保存 DOM 节点,不容易造成内存泄漏
  • Map
    • 本质上是键值对的集合,类似集合
    • 可以遍历,方法很多,可以跟各种数据格式转换
  • WeakMap
    • 只接受对象最为键名(null 除外),不接受其他类型的值作为键名
    • 键名是弱引用,键值可以是任意的,键名所指向的对象可以被垃圾回收,此时键名是无效的
    • 不能遍历,方法有 get、set、has、delete

# 7. 箭头函数与普通函数的区别是什么?

查看答案

箭头函数是普通函数的简写,可以更优雅的定义一个函数,和普通函数相比有以下几点差异:

  1. 函数体内的 this 指向不同
  2. 不可以使用 arguments 对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
  3. 不可以使用 yield 命令,因此箭头函数不能用作 Generator 函数。
  4. 不可以使用 new 命令,因为:
  • 没有自己的 this,无法调用 call,apply。
  • 没有 prototype 属性 ,而 new 命令在执行时需要将构造函数 的 prototype 赋值给新的对象的__proto__

# 8. 箭头函数不适用的场景

查看答案
  1. 构造函数原型方法(需要使用this获得实例对象)
  2. arguments(箭头函数中没有)
  3. 执行上下文的this(上下文中的this需要推断)
  4. dom的事件回调(this指元素本身非window)

# 9. class继承的原理是什么?

查看答案

原理是组合式继承。

# 10. includes和indexOf都可以在数组中查找元素,这两者有啥区别?

查看答案

indexOf是ES5就有的查找数组元素的方法,找不到就返回-1,找到了返回索引值,但是不能查找NaN

[NaN].indexOf(NaN) => -1
1

includes是ES6中新增的查找数组的方法,这个方法专门是判断数组中是否存在某个元素,返回true/false,包括查找NaN

[1,2,3].includes(2) => true
[NaN].includes(NaN) => true
1
2

# 11. Object spread和Object.assign的区别?

查看答案
更新时间: 2022-04-10 13:23