# fed-e-task-01-02 **Repository Path**: duckking/fed-e-task-01-02 ## Basic Information - **Project Name**: fed-e-task-01-02 - **Description**: fed-e-task-01-02 拉勾part1 模块二作业 - **Primary Language**: JavaScript - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2020-11-04 - **Last Updated**: 2021-11-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 简答题 一、请说出下列最终的执行结果,并解释为什么 ```js var a = [] for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i) } } a[6]() ``` 答:输出结果为10。此处 i 为全局变量, 当函数执行时for循坏已经执行完毕,而函数内部 i 为全局变量,因此执行时函数中得到的 i 值为10。 二、请说出下列最终的执行结果,并解释为什么。 ```js var tmp = 123; if (true) { console.log(tmp) let tmp } ``` 答:执行报错ReferenceError: Cannot access 'tmp' before initialization。因为let标识符声明会形成一个闭包使得 if 区域变为块级作用域,而变量查找则首先从当前作用域查找再逐级向上查找,因此先查找到 let 声明的 tmp ; 而 let 声明的变量 其使用必须在变量声明之后,因此此处会报 tmp “变量初始化前无法访问”的错误。 三、结合ES6新语法,用最简单的方式找出数组中的最小值 ```js var arr = [12, 34, 32, 89, 4] ``` 答: ```js // 在数学查找最小值函数中使用数组展开符 Math.min(...arr) ``` 四、请详细说明var, let, const三种声明变量的方式之间的具体差别。 答: **var**: 不会形成闭包,因此无法实现块级作用域; 变量声明会提升到最开始,书写代码时声明变量可以在使用变量之后; 变量声明时可以不赋初始值,之后也可以重新赋值 **let**:会形成闭包以此实现块级作用域; 变量声明不会提升到最开始,因此变量使用不可以在声明变量之前;变量声明时可以不赋初始值,之后也可以重新赋值 **const**:会形成闭包以此实现块级作用域;变量声明时必须赋初始值且之后不允许被修改内存地址 五、请说出下列代码最终输出的结果,并解释为什么。 ```js var a = 10; var obj = { a: 20, fn () { setTimeout(() => { console.log(this.a) }) } } obj.fn() ``` 答: 输出结果为20。因为箭头函数当中没有 this 的机制,因此箭头函数中的 this 会获取外层的 this ,即 与外部 this 一致。因此 this.a 实际为 obj 函数的 this.a ,输出结果为20。 六、简述 Symbol 类型的用途。 答:Symbol最主要的作用就是为对象添加独一无二的属性名,因为其创建的值唯一且不能重复,因此在协同项目时能够避免变量/属性名同名重复的冲突。除此之外由于Symbol的值独一无二还可以模拟实现对象的私有成员。 七:说说什么是浅拷贝,什么是深拷贝? 答: **浅拷贝**: 只复制指向对象的指针,而不复制引用对象本身,即指向同一个内存空间,当修改其中一个对象时可能影响到另外一个对象 **深拷贝**: 复制引用对象本身,两者的内存空间不一致,因此修改其中一个并不影响另一个对象 八、请简述 TypeScript 与 JavaScript 之间的关系。 答: TypeScript 是 JavaScript 的超集或者是扩展集, 结合 JavaScript 类型系统以及 ES6之后版本 特性,最终会编译为原始的 JavaScript 。在 TypeScript 中可以使用原生的 JavaScript 进行代码编写, 而在 JavaScript 中则不能够直接使用 TypeScript 扩展的书写方式,如类型注解、接口等。 九、请谈谈你所认为的 TypeScript 优缺点。 答: **优点**: - 能够避免类型异常,提高编码效率以及可靠程度,避免编写功能偏差 - 支持自动转换新特性,对于转换编译成 JS 文件的规范可以低至 ES3 - 兼容性强,任何一种 JavaScript 运行环境都支持,且可以直接使用 JavaScript 进行代码编写 - 功能更强大,环境生态更健全、更完善 - 降低长期维护项目的成本,能够减少维护成本 **缺点**: - 学习成本较高,相对于JavaScript多了许多新概念,如: 接口、泛型、枚举等 - 由于需要进行类型定义因此在项目初期会增加时间成本,代码的编写效率相比JS会有所降低 - 对于部分插件的结合不够完美 十、描述引用计数的工作原理和优缺点。 答: **工作原理**:给每个创建的对象设置引用数,当声明一个变量并将引用类型值赋给该变量时引用数就为1,此后再被引用则引用数加1,而相关对象调用完毕后引用数减1,当引用数字为0时就会被当成垃圾对象立即回收。 **优点**: - 发现垃圾时立即回收,不长时间占据内存空间 - 由于其时刻监控,保证内存不会被沾满,因此最大限度减少程序暂停 **缺点**: - 无法回收循环引用的对象 - 由于需要时刻监控数值,当多个数值修改时时间消耗大,因此时间开销大 十一、描述标记整理算法的工作流程。 答:首先遍历对象找到所有的活动对象进行标记,然后对标记对象、未标记对象进行整理,移动标记对象的位置,使得对象在地址上产生连续,然后回收未标记对象。 十二、描述V8中新生代存储区垃圾回收的流程。 答: - 将所有的活动对象存放在From空间 - From空间中对活动对象进行标记,并整理标记、未标记对象使空间变得连续 - 将活动对象拷贝至To空间 - From与To交换空间,然后释放原来From空间的所有对象 十三、描述增量标记算法在何时使用及工作原理。 答:增量标记算法在标记清除以及标记整理的标记阶段进行使用 **工作原理**:在遍历活动对象进行标记时,执行一部分程序后遍历该部分的活动对象并进行标记,接着继续执行一部分程序遍历并标记该部分的活动对象,如此反复几次后进行垃圾回收。这使得标记与程序交替进行。