# 1 请说出下列最终的执行结果,并解释为什么

var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i)
  } 
}
a[6]()   

输出10,a和i是全局变量,在调用a6函数是,i值已经是循环10次之后的值

# 2 请说出下列最终的执行结果,并解释为什么

var tmp = 123;

if(true) {
  console.log(tmp)
  let tmp
}

报错 tpm is not defined 在if下面的块级作用域中,会先在此作用域中将tmp进行变量提升 但是在es6中,let声明的tmp提升到块顶部,但是还没有进行赋值操作,会报错

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

var arr = [12, 34, 32, 89, 4]
// 答案
let mix = Math.min(...arr)
console.log(mix)  // 4

# 4 请详细说明var let const 三种声明变量的方式之间的具体差别

  • var是全局变量,不存在块级作用域,只有全局作用域和函数作用域
  • let和const存在块级作用域,块级作用域是访问不到的
  • let声明的变量可修改,const只能定义常亮,不可修改,切初始值不可为空
  • var存在变量提升,const和let存在暂时性死区

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

  var a = 10;
  var obj = {
    a: 20,
    fn () {
      setTimeout(() => {
        console.log(this.a) 
      });
    }
  }
  obj.fn()

输出20 箭头函数中不改变this指向,即定义函数的时候this已经绑定 即obj而不是window,而不是在执行函数的时候绑定

# 6 简述Symbol类型的用途?

  • Symbol为一种新定义的数据类型,每个值都只有唯一的一个值
  • 1 Symbol不能通过Object.keys或for...in 来枚举对象的属性名 所以,我们可以把一些不需要对外操作和访问的属性使用Symbol来定义
  • 2 json.stringify会被排除在输出内容之外

# 7 说说什么是浅拷贝,什么是深拷贝

  • 浅拷贝只是把对象的引用拷贝过来,在新的对象上操作会影响源对象
  • 深拷贝是完全新定义一个指针,在把值拷贝过来,新的对象上操作不会影响原对象
  • 一些深拷贝的常见方法 json.parse(JSON.stringify()) slice() concat() 递归

# 8 请简述TypeScript 与 JavaScript之间的关系

  • TypeScript是基于JavaScript上的语言
  • TypeScript是JavaScript的超集,在javaScript上多了一些类型系统和对es6的支持
  • TypeScript最终会被编译成原始的JavaScript

# 9 请谈谈你所认为的TypeScript优点

  • 静态类型化,允许开发人员编写更健壮的代码并对其进行维护
  • 大型的开发项目,使用TypeScript工具来进行重构更容易、便捷
  • 类型安全,在编译期间即可检测错误
  • es6 自动完成和动态输入有助于开发任重提高工作效率

# 10 描述引用计数的工作原理和优缺点

  • 设置引用数,判断当前引用数是否为0,为0时垃圾回收机制进行回收
  • 引用关系改变时修改引用数字,当有数值引用时 +1 减少时 —1
  • 通过判断引用数值是否为0来判断当前对象是否为一个垃圾
  • 优点: 发现垃圾时立即回收,可以最大限度的尖山程序暂停
  • 缺点:对循环引用的对象无法回收,引用计数算法的时间开销大

# 11 描述标记整理算法的工作流程

  • 标记整理算法可以看做是标记清除的增强
  • 标记阶段的操作和标记清楚一致
  • 清除阶段会先执行整理,移动对象位置

# 12 描述V8中新生代存储区垃圾回收的流程

  • V8内存空间一分为二(左侧为新生代储存)
  • 小空间用于存储新生代对象(32M|
  • 使用空间为From,空闲空间为To
  • 活动对象存储于From空间
  • 标记整理后将活动对象拷贝至To

# 13 描述增量标记算法在何时使用及工作原理

  • 在V8清除老生代对象时为提高清除效率优化时使用