一、请说出下列最终的执行结果,并解释为什么。
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
}
}
a[6]();
答:结果是10
。因为for
循环里的i
是全局变量,for
循环执行完之后,i
已经变成了10
,所以之后无论调用a
几,输出的都是10
。
二、请说出下列最终的执行结果,并解释为什么。
var tmp = 123;
if (true) {
console.log(tmp);
let tmp;
}
答:结果报错,cannot access 'tmp' before initialization
原因:let
会形成块级作用域和封闭作用域,所以tmp
无法拿到外层 var
声明的值,只能在块级作用域中查找。let
不会导致变量提升,因此console.log(tmp)
无法找到声明,出现暂时性死区。
三、结合ES6
新语法,用最简单的方法找出数组中的最小值。
var arr = [12, 34, 32, 89, 4];
答:
arr.sort((a, b) => a - b)[0]
arr.reduce((min,num) => min < num ? min : num)
Math.min(...arr)
四、请详细说明 var
,let
,const
三种声明变量方式之间的具体差别。
var |
let |
const |
|
---|---|---|---|
提升 | 声明提升,使用undefined 初始化 |
不存在变量提升 | 不存在变量提升 |
作用域 | 全局 | 块级 | 块级 |
初始化 | 可以仅声明不初始化 | 可以仅声明不初始化 | 必须在声明时初始化 |
重复定义 | 可以 | 不可以 | 不可以 |
多次赋值 | 可以 | 可以 | 基本数据类型不可以,引用数据类型仅可改变值 |
声明前访问 | 可以 | 不可以 | 不可以 |
五、请说出下列代码最终输出的结果,并解释为什么。
var a = 10;
var obj = {
a: 20,
fn() {
setTimeout(() => {
console.log(this.a);
});
}
}
obj.fn();
答:打印20
。因为setTimeout
是箭头函数,里面的this
指向没有改变和fn
函数里的this
是一致的都指向obj
,所以会输出20
六、简述Symbol
类型的用途。
答:
- 作为对象的属性,可以作为对象的私有属性,
- 阻止对象上属性名的冲突,每个
Symbol
都独一无二的,可以保证不与其他属性名产生冲突, - 使用
Symbol
来替代常量
七、说说什么是浅拷贝,什么是深拷贝。
答:
- 浅拷贝:针对
Object
,Array
这种复杂数据类型,浅拷贝复制一层对象的属性,属性中的值是基本数据类型直接复制值,如果是引用类型复制内存地址的指针,所以在修改复制后的变量里引用类型的里面的值时,会导致原始数据也被修改 - 深拷贝:针对
Object
,Array
这种复杂数据类型,深拷贝递归复制了所有的层级,新数据和原始数据不存在联系,因此在修改复制后的变量里引用类型的里面的值时,不会导致原始数据也被修改
八、简述TypeScript
和JavaScript
之间的关系。
答:TypeScript
并不是一个完全新的语言, 它是 JavaScript
的超集,为 JavaScript
的生态增加了类型机制,并最终将代码编译为纯粹的 JavaScript
代码。
TypeScript |
JavaScript |
---|---|
JavaScript 的超集用于解决大型项目的代码复杂性 |
一种脚本语言,用于创建动态网页。 |
可以在编译期间发现并纠正错误 | 作为一种解释型语言,只能在运行时发现错误 |
强类型,支持静态和动态类型 | 弱类型,没有静态类型选项 |
最终被编译成 JavaScript 代码,使浏览器可以理解 | 可以直接在浏览器中使用 |
支持模块、泛型和接口 | 不支持模块,泛型或接口 |
支持 ES3 ,ES4 ,ES5 和 ES6 等 |
不支持编译其他 ES3 ,ES4 ,ES5 或 ES6 功能 |
社区的支持仍在增长,而且还不是很大 | 大量的社区支持以及大量文档和解决问题的支持 |
九、请你谈谈你所认为的TypeScript
优缺点。
优点:
- 任何一种
javascript
运行环境都支持 - 功能更为强大,生态更健全、更完善
-
TypeScript
属于渐进式的 - 增强代码的可读性和可维护性,增强了编译器和
IDE
的功能,定义可以作为文文档 - 在编译阶段就可以发现大部分大错误,不需要在运行时才发现
缺点:
- 语言本身多了很多概率,提高学习成本
- 项目初期,
TypeScript
增加开发成本 - 集成到构建流程需要一些工作量
- 可能和一些库结合不完美,需要单独添加一些声明,不过大部分的库都支持了
TypeScript
十、描述引用计数的工作原理和优缺点。
工作原理:设置引用数,判断当前引用数是否为 0
,引用关系改变时修改引用数字
优点:
- 发现垃圾时立即回收
- 最大限度减少程序暂停(保证空间不会被占满)
缺点:
- 无法回收循环引用的对象
- 时间开销大(监控对象,维护引用数)
十一、描述标记整理算法的工作流程。
-
遍历所有对象找标记活动对象
-
清除阶段会先执行整理,移动对象位置,将活动对象放在一起
-
清除没有标记的对象,同时把第一次遍历所做的标记抹掉
-
把回收的空间放到空闲列表上面,方便后续程序申请空间使用
优点: 减少了内存空间的碎片化,缺点: 不能立即回收对象
十二、描述V8
中新生代存储区垃圾回收的流程。
- 回收过程采用复制算法 + 标记整理算法
- 新生代分为
from-to
两个等大空间32M
(32位为
16M`) - 使用空间为
from
内存区,空闲空间为to
内存区,当from
空间应用一定大小会触发标记整理 - 当发生标记整理后,复制活动对象到
to
内存区,然后from
空间进行内存释放。 - 如果拷贝时出现晋升,将新生代活动对象移入老生代
- 当
To
空间的使用率达到25%
时,将新生代活动对象移入老生代 - 当一轮
GC
执行完毕后还存活的新生代测需要晋级 - 当一次
GC
操作后,From
和to
需要进行置换
十三、描述增量标记算法在何时使用及工作原理。
答: 使用时机:会穿插在程序的运行中执行。
工作原理: 对象存在直接可达和间接可达,将遍历对象标记,拆分成多个小步骤,先标记直接可达对象。间接可达的标记与程序执行交替执行,最终完成清除。
网友评论