模块一 part1

248 阅读3分钟

模块一 part1

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

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

var 声明的变量会被添加到最近的环境中,这里是全局环境,会作为全局变量对象的属性。函数调用时,循环已经,i 变成了 10,所以打印出的结果为 10

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

var tmp = 123

if (true) {
    console.log(tmp) // 引用错误, 在 tmp 声明前使用
    let tmp
}

let 和 const 声明的变量拥有块级作用域,并且没有变量声明提升,因此在变量声明前都无法使用(暂时性死区,temporary dead zone)

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

const arr = [12, 34, 32, 89, 4]

Math.min(...arr) // 4

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

开始执行你第一行Javascript脚本代码的时候,它就会创建一个全局执行上下文,包括以下几个方面: 创建词法环境,创建变量环境。

词法环境由下面三部分组成: • 环境记录; • 外部环境引用; • 绑定this;

var 属于变量环境导致了它截然不同的语言特性,这就解释了为什么 var 没有块级作用域,因为变量环境内部创建过程不一样。let const 属于词法环境的环境记录

let和const定义的变量a和b在创建阶段没有被赋值,但var声明的变量从在创建阶段被赋值为undefined。

这是因为,在创建阶段,会在代码中扫描变量和函数声明,然后将函数声明存储在环境中,但变量会被初始化为undefined(var声明的情况下)和保持uninitialized(未初始化状态)(使用let和const声明的情况下)。

这就是为什么使用var声明的变量可以在变量声明之前调用的原因,但在变量声明之前访问使用let和const声明的变量会报错(TDZ)的原因。

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

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

this 指向函数运行时所在环境的变量对象,即 this 指向函数的调用者,但箭头函数本身没有 this,它的 this 在定义时确定,指向最近作用域中的 this,这里是 fn 函数中的 this,而 fn 函数中的 this 的指向在 fn 函数调用时确定,为其调用者 obj,因此箭头函数中的 this 指向 obj

六、简述 Symbol 类型的用途

symbol 值具有唯一性,可以作为标识符,作为对象的属性名,以保证不会出现同名属性,有效防止对象某一个键不小心被改写或者覆盖的情况,正因为如此,其可以用来模拟实现对象的私有属性

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

深拷贝:拷贝前后的两个对象之间没有任何互相引用 浅拷贝:拷贝前后的两个对象之间的引用类型为同一个值

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

TS 是 JS 的超集,增强了 JS 并为其增加了类型系统,可以编译成纯 JS

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

优点

增加代码可读性、可维护性,在编译阶段就可以发现大部分错误

缺点

迁移成本大

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

设置引用计数器,判断当前引用数是否为 0,为 0 则立即回收

优点

垃圾立即回收 最大限度减少程序暂停(减少内存不够用的情况)

缺点

无法回收循环引用的对象 内存开销大(因为要维护计数器)

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

遍历所有对象,先进行整理(移动位置),在删除没有标记的对象(不活动、不可达的对象),以腾出连续的内存空间

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

首先将新生代内存空间一分为二(from 和 to),from 部分表示正在使用的内存,to 则是目前闲置的内存 GC 操作时,先检查 from 部分,将其中的存活对象复制到 to 中,非存活对象直接回收

当 from 中所有的存活对象按顺序进入到 to 中后(解决内存碎片问题),两者角色互换,from 变成 to(闲置的内存),to 变成 from(正在使用的内存)

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

JS 是单线程执行的,V8 在进行 GC 操作时,会阻塞业务逻辑的执行,影响性能。为了避免这样的问题,V8 采用了增量标记的方式,即将程序执行和标记整理各分成若干小部分,两者交替执行,类似于操作系统中线程的并发执行