ES6
狐七 3/21/2022 js
# 1. ES6 代码转成 ES5 代码的实现思路?
查看答案
ES6 转 ES5 目前行业标配是用 Babel,转换的大致流程如下:
- 解析:解析代码字符串,生成 AST
- 转换:按一定的规则转换、修改 AST
- 生成:将修改后的 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引擎不会用新值覆盖之前旧值的内存空间(虽然从写代码的角度来看,确实像是被覆盖掉了)。
而是:
- 重新分配一个新的内存空间来存储新值
- 将新的内存地址与变量进行绑定
- JS引擎会在合适的时机进行GC,回收旧的内存空间。
const定义变量(常量)后,变量名与内存地址之间建立了一种不可变的绑定关系,阻隔变量地址被改变。
当 const 定义的变量进行重新赋值时,根据前面的论述,JS引擎会尝试重新分配新的内存空间,所以会被拒绝,便会抛出异常。
# 4. 全局作用域中,用 const 和 let 声明的变量不在 window 上,那在哪里获取?
查看答案
- var和function声明的全局变量,依旧是顶层对象的属性,使用的时候可以用window.变量获取。
- let、const、class声明的全局变量,不属于顶层对象的属性,只是一个块级作用域(Script)中,使用的时候在块级作用域中就可以获取,不加window。
# 5. 什么时候回出现暂时性死区(TDZ)
查看答案
- 声明let、const之前
- 函数参数赋值默认值之前,默认值为undefined
# 6. Set、Map、WeakSet 和 WeakMap 的区别?
查看答案
- Set
- 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用
- WeakSet
- 成员都是对象,成员都是弱引用
- 可以被垃圾回收机制回收
- 可以用来保存 DOM 节点,不容易造成内存泄漏
- Map
- 本质上是键值对的集合,类似集合
- 可以遍历,方法很多,可以跟各种数据格式转换
- WeakMap
- 只接受对象最为键名(null 除外),不接受其他类型的值作为键名
- 键名是弱引用,键值可以是任意的,键名所指向的对象可以被垃圾回收,此时键名是无效的
- 不能遍历,方法有 get、set、has、delete
# 7. 箭头函数与普通函数的区别是什么?
查看答案
箭头函数是普通函数的简写,可以更优雅的定义一个函数,和普通函数相比有以下几点差异:
- 函数体内的 this 指向不同
- 不可以使用 arguments 对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
- 不可以使用 yield 命令,因此箭头函数不能用作 Generator 函数。
- 不可以使用 new 命令,因为:
- 没有自己的 this,无法调用 call,apply。
- 没有 prototype 属性 ,而 new 命令在执行时需要将构造函数 的 prototype 赋值给新的对象的
__proto__
# 8. 箭头函数不适用的场景
查看答案
- 构造函数原型方法(需要使用this获得实例对象)
- arguments(箭头函数中没有)
- 执行上下文的this(上下文中的this需要推断)
- 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
2