ES 新特性与 TypeScript、JS 性能优化
简答题
一、请说出下列最终的执行结果,并解释为什么。
1 | var a = []; |
最终结果是在控制台输出 10;for 循环中使用 var 定义变量没有块级作用域,在 a[6]方式执行的时候会根据 js 的词法作用域向上查找找到的 i 是已经经过++操作的 10;
二、请说出下列最终的执行结果,并解释为什么。
1 | var tmp = 123; |
最终结果会出现引用错误;在 if 的代码块中出现了 let 声明变量,所以在 if 代码块中就出现了 tmp 变量的暂时性死区,js 的编译器会抛出引用错误;
三、结合 ES6 新语法,用最简单的方式找出数组中的最小值。
1 | var arr = [12, 34, 32, 89, 4]; |
1 | Math.min(...arr); |
四、请详细说明 var, let, const 三种声明的方式之间的具体差别。
var 声明变量是会出现变量提升,而 let 和 const 不会;var 可以重复定义,而 let 和 const 不行;let 和 var 定义的变量可以被改变,而 const 不可以;
五、请说出下面代码最终输出的结果,并解释为什么。
1 | var a = 10; |
执行的结果是 20;箭头函数不改变运行时 this 的指向,所以 log 中的 this 指向距离最近的 fn 中的 this,以上代码等同于
1 | var a = 10; |
六、简述 Symbol 类型的用途。
Symbol 可以声明一个独一无二的变量可以用作对象的键,可以用来做依赖注入中的服务名称或者控制器名称。同时 Symbol 中中定义了一些常量可以用来迭代数组等等。
七、说说什么是浅拷贝,什么是深拷贝?
浅拷贝是指将”引用”的地址存储在变量中,该地址中的某一些变化可以通过新变量访问;深拷贝是将”引用”通过递归等手段将其中”值”分别赋值;
八、请简述 Typescript 和 Javascript 之间的关系。
javascript 可以直接运行在 V8 引擎中,而 ts 需要通过 tsc 将 ts 代码编译成 js 代码才能运行在 v8 上;在 es6 没有普及的时候可以通过 ts 使用 javascript 中的高级语法;
九、请谈谈你所认为的 Typescript 优缺点。
typescript 可以大大降低在生产中类型引起的一系列问题,因为在 ts 编译的时候会进行类型检查;在 ts 中可以自由的使用 js 中的一些没有普及的语法;但是 ts 学习成本比较高,在已有的项目中使用 ts 会存在大量代码重构带来的高成本;
十、描述引用计数的工作原理和优缺点。
引用计数用来记录当前有多少指针指向同一块动态分配的内存。当有指针指向这块内存时,计数器加 1;当指向此内存的指针销毁时,计数器减 1。当引用计数为 0 时,表示此块内存没有被任何指针指向,此块被共享的动态内存才能被释放。
当变量循环引用时无法判断变量是否需要销毁,导致无法判断内存泄漏;优点就是算法相对来说比较简单容易实现;发现垃圾时立即回收;最大限度减少程序暂停
十一、描述标记整理算法的工作流程。
标记整理可以看做是标记清除的加强算法;标记阶段的操作和标记清除一致;清除阶段会先执行整理,移动对象位置,整理内存;
十二、描述 V8 中新生代存储区垃圾回收的流程。
V8 内存一分为二,小空间用于存储新生代对象(32M|16M)用于回收存活时间比较短的对象;回收过程采用复制算法+标记整理;新生代内存区分为二个等大小空间;使用空间为 From,空闲空间为 To;活动对象的存储于 From 空间;标记整理后将活动对象拷贝 To;From 与 To 交换空间完成释放。
十三、描述增量标记算法在何时使用以及工作原理。
在 V8 清除老生代对象时为提高清除效率优化时使用;清除时,程序执行然后遍历对象进行标记,之后交替执行程序和增量标操作,标记完成后,进行清除操作,完成垃圾回收;