1. 闭包
闭包可以说是JavaScript
最强大的特性了,很多功能都是依靠闭包来实现的,比如高阶函数。
1.1 什么是闭包?
先引用MDN上的一段话:
函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起构成闭包(closure)。也就是说,闭包可以让你从内部函数访问外部函数作用域。在 JavaScript 中,每当函数被创建,就会在函数生成时生成闭包。
从上面的语句中我们可总结出:
- 组成:函数以及对函数外层的环境的引用。
- 产生:创建函数时就会形成闭包。
- 原因:
JavaScript
的作用域链。
1.2 如何让下面的代码按期望输出?
我们希望下面的代码输出“1 2 3 4 5”结果却输出“6 6 6 6 6”,请解决
for (var i = 1; i <= 5; i++) {
setTimeout(function () {
console.log(i)
}, 1000)
}
解法1
使用let
代替var
来定义变量,形成块级作用域。
for (let i = 1; i <= 5; i++) {
setTimeout(function () {
console.log(i)
}, 1000)
}
解法2
使用立即执行函数返回闭包,setTimeout
的回调函数引用了外层作用域的变量,形成了闭包。
for (var i = 1; i <= 5; i++) {
(
(j) => {
setTimeout(() => console.log(j), 1000)
}
)(i)
}
1.3 闭包的优点
- 将函数与其操作的某些数据或者环境关联起来。
- 用闭包模拟私有方法,每个闭包可以引用专属于自己的独立作用域
1.4 闭包的缺点
内存泄漏,因为GC的规则是当某些对象不再被引用,或者相互引用并成为孤岛了(多棵树或者多个图),那么对象占用的内存空间将会被回收,而闭包引用了已经弹出执行栈并被回收的函数的作用域,所以会过多的占用内存。
1.5 闭包的应用场景
- 接收一个函数并返回一个新的函数,感觉有点类似于
bind
,不过bind
绑定的是我们传入的值,这个值保存到了返回给我们的函数中,而闭包却把绑定的值放在了另一作用域中。 - 扩展全局对象,并保护私有变量
- 延长局部变量的生命
2. 原型和原型链
2.1 请简要说一下你对原型以及原型链的理解
通常JavaScript
被称之为一种基于原型的语言,即每个对象都有一个原型对象(prototype
),对象实例以其原型为模板,从原型上继承属性和方法,而原型对象也会有它自己的原型,一层一层以此类推,直到原型为null
,这就是原型链。
2.2 原型继承的方法
可以通过Object.setPrototypeOf()/Reflect.setPrototypeOf()
来给对象设置原型,不过这样的方法性能很差,推荐直接使用Object.create()
来实现。
3. 同步异步
3.1 如何理解同步和异步?
本质上的区别是:发起请求后获取消息结果的行为是主动的还是被动的,如果是主动的就是同步,反之则是异步。
- 同步阻塞:发起请求后一直在等待应答,有应答后请求应答,不执行后面的代码
- 同步非阻塞:发起请求后,可以先去执行后面的代码,但是会一直轮询发起的请求是否有应答。
- 异步阻塞:发起请求后一直等待应答,不做其他事情。
- 异步非阻塞:发起请求后先执行后面的代码,然后服务端应答后主动通知请求方
4. EventLoop
4.1 JavaScript为什么是单线程的?
- 因为设计者当初认为它只是在浏览器执行的脚本语言,对它的性能要求不高,并且不期望它变得很复杂
- 因为
JavaScript
可以改变DOM
结构,如果多线程的话就会很复杂。
4.2 什么是runtime
我认为runtime
可以通俗的理解为“库”,即实现某些语言特性所必须的代码,比如Chrome
提供了DOM
,BOM
,而Node.js
提供了requrie
和Process
。所以runtime
就好比一个语言实现的基础代码,正如其名[运行时所必须的东西]。
4.3 什么是EventLoop?
事件循环EventLoop
是让JavaScript
做到既是单线程,又不会阻塞的核心机制,也是JavaScript
并发模型的基础,用来协调各种事件,用户交互,脚本执行,UI渲染,网络请求的一种机制。总的来说,EventLoop
是实现异步回调的一种机制。每个线程都拥有自己的事件循环,它们可以独立运行。
另外,事件循环其实并不是ECMAScript
规范中的内容,而是定义在HTML
标准中的,而V8
等引擎只是实现了ECMAScript
规范中的内容,所以事件循环是属于runtime
的。
4.4 宏任务都有哪些?
-
DOM
操作 - 用户交互,事件之类的
- 网络请求
-
history api
操作 -
setTimeout/setInterval
等
4.5 微任务都有哪些?
标准中被没有规定微任务都有哪些,不过一般都认为有以下几种:
Promise
MutationObserver
-
Process.nextTick
,Node平台
网友评论