模块二:ES 新特性与 TypeScript、JS 性能优化

438 阅读5分钟

简答题

一、请说出下列最终的执行结果,并解释为什么?

var a = [];
for (var i =0; i< 10; i++) { // i 是在全局作用域下的变量, 循环中, i被不断地重新赋值, 最终是 10即(window.i = 10a[i] = function () {   // 循环的时候,函数未执行
        console.log(i)
    }
}
a[6]() // 10  函数执行,当前的this指向window,window.i = 10

二、请说出下列最终的执行结果,并解释为什么?

var tmp = 123;

if (true) { 
    console.log(tmp) // 因为在最近的{}作用域里,有定义tmp,所以不会使用全局的tmp. 在这作用域里,这时候还没定义就使用所以会报错(未定义)
    let tmp  // tmp 是局部作用域, 就近原则
}

三、结合ES6新语法、用最简单的方式找出数组中的最小值

let arr = [12, 34, 32, 89, 4]
function getSmall (array) {
    return array.reduce( (accumulator, currentValue) => { // 箭头函数
        return accumulator >= currentValue ? currentValue : accumulator
    })
}
console.log(getSmall(arr))

四、请说出var, let, const 三中声明变量方式之间的具体区别

  • var 没有块级作用域概念,在作用域中会变量提升(提升到作用域的顶部, 创建过程、和初始化都被提升)。在作用域中, 可以先使用后声明,同一变量可以重复声明, 挂在全局对象下、可以被重新赋值

  • let 块级作用域, 声明之前不可以使用,形成暂时性死区。 同一个块级作用域下, 同一变量不可重复声明,不属于全局对象, 也有变量提升(创建被提升,初始化没有被提升),可以被重新赋值

  • const 和let 的区别是不可以被重新赋值

五、请说出下列代码最终输出的结果,并解释为什么

var a = 10;
var obj = {
    a: 20,
    fn () { // obj调用fn这时这里的this 指向obj
        setTimeout(() => { //箭头函数本身没有this, 会把该作用域的上下文绑定该作用域上,所以这里的this也就指向了obj
            console.log(this.a) // 所以20
        })
    }
}
obj.fn()

六、简述Symbol类型的用途

  • 定义常量
  • 定义对象的toString结果
  • 作为对象属性名(key)Symbol是独一味二的
  • 模拟实现私有成员
  • 注册和获取全局Symbol
  • 迭代器

七、说说什么是浅拷贝,什么是深拷贝

浅拷贝:拷贝的是指向对象的引用(对象在堆中的地址)。修改会直接修改对象。原始数据类型没有深拷贝、浅拷贝之分 深拷贝:拷贝整个对象的值(对象在堆中的数据), 修改的是复制的对象, 不会影响原对象。

八、请简述TypeScript与JavaScript之间的关系

TypeScript 是 JavaScript 的一个超集,支持 ES+ ts 在 js 之上,添加了类型系统,ts最终会编译成js

九、请谈谈你所认为的TypeScript优缺点

优点

* 类型系统。增加了代码的可读性和可维护性,在编译时候就可发现大部分的错误(语法,类型),增强编辑器的功能
* 包容性,js文件可以直接改成 ts 文件,不定义类型可自动推论类型,可以定义几乎一切类型,ts 编译报错时也可以生成 js 文件,兼容第三方库,即使不是用ts编写的
* 有活跃的社区,大多数的第三方库都可提供给 ts 的类型定义文件,完全支持 es6 规范

缺点

* 增加学习成本,需要理解接口(Interfaces)和泛型(Generics),类(class),枚举类型(Enums) 
* 短期增加开发成本,增加类型定义,但减少维护成本。小项目比较不划算
* 和有些库结合时不是很完美, 需要自己声明类型

十、描述引用计数的工作原理和优缺点

原理

为对象的引用计数。根据当前引用的引用数是否为0, 引用关系改变了修改引用数, 引用数为0 的时候, 立即回收

优点

  • 发现垃圾立即回收
  • 最大限度减少程序暂停

缺点

  • 无法回收循环引用的对象
  • 时间开销大

十一、描述标记整理算法的工作流程

  • 分标记和清除整理两个阶段
  • 标记阶段:遍里所有所有对象找标记活动对象
  • 清除阶段:遍里所有对象,先执行整理移动对象位置,然后清除没有标记对象

十二、描述V8中新生代存储区垃圾回收的流程

  • 回收过程采用复制算法+标记整理
  • 新生代内存分区为两个等大小的空间
  • 使用空间From, 空闲空间为TO
  • 活动对象存储在From空间
  • 标记整理后将活动对象拷贝至To
  • From 和 To 交换空间完成释放

十三、描述增量标记算法在何时使用及工作原理

何时使用

增量标记算法是V8引擎清除老生代对象是为提高清除效率优化时使用的,因为在进行垃圾回收的操作式,也是会阻塞程序的执行, 所以在清除老生代垃圾是在程序执行的空档期去执行回收垃圾操作,此时就可以使用增量标记算法。它是将当前一整段的垃圾回收操作,分成多个小段组合法去完成。实现垃圾回收和程序执行交替完成。这样可以让时间消耗更合理,效率优化

工作原理

  • JS程序执行过程中,会伴随着垃圾回收的工作
  • 当垃圾回收工作时,需要遍历对象进行标记,此时不需要将所有对象进行标记,可以先将直接可达的对象进行标记,标记完成后暂停标记
  • 然后让JS程序执行一会,再让GC机制去做二步标记,将间接可达的对象进行标记,标记完成后暂停标记
  • 重复以上两个操作,让程序执行和垃圾回收的标记操作交替执行,来达到优化效率和提升用户体验的目的
  • 直到标记全部完成后,执行垃圾回收

示意图