美文网首页
面试题整理-JavaScript(中)

面试题整理-JavaScript(中)

作者: 前端艾希 | 来源:发表于2020-05-17 23:56 被阅读0次

    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为什么是单线程的?

    1. 因为设计者当初认为它只是在浏览器执行的脚本语言,对它的性能要求不高,并且不期望它变得很复杂
    2. 因为JavaScript可以改变DOM结构,如果多线程的话就会很复杂。

    4.2 什么是runtime

    我认为runtime可以通俗的理解为“库”,即实现某些语言特性所必须的代码,比如Chrome提供了DOMBOM,而Node.js提供了requrieProcess。所以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平台

    参考文档

    前端内参

    相关文章

      网友评论

          本文标题:面试题整理-JavaScript(中)

          本文链接:https://www.haomeiwen.com/subject/pnqyohtx.html