2020前端面试 - JavaScript2.0篇

前言:

个人觉得面试其实是一个自我学习的过程,如果说短时间内找不到工作,那一定是你面的还不够多,不要气馁,不要放弃,在心底告诉自己,下一次面试,再下一次面试,一定能够拿到OFFER。

平常开发过程中,可能疏于学习,但是面试的时候,就逼得你不得不去学习一些新的东西,巩固一些基础的知识。

在面试中进取,你会发现不懂的东西还有那么多,对于未来发展方向和把控也有一定的认知和理解,所以,我觉得这是一件好事,一个自我充电的过程。

希望总结的知识,能够帮到更多的人,有些东西,我也还在摸索中,一起学习吧!少年~~

1. 钩子函数和回调函数的区别
  • 很明显的差别就是:钩子函数在捕获消息的第一时间就执行,而回调函数是捕获结束时,最后一个被执行的。

  • 回调函数其实是调用者将回调函数的指针传递给了调用函数,当调用函数执行完毕后,通过函数指针来调用回调函数。而钩子函数在消息刚发出,没到达目的窗口前就先捕获了该消息,先得到控制权执行钩子函数,所以他可以加工改变该消息,当然也可以不作为,还可以强行结束该消息。

2. MVC模式
  • 所有通信都是单向的。

  • MVC模式的意思是,软件可以分成三个部分
    1.视图(View):用户界面。
    2.控制器(Controller):业务逻辑
    3.模型(Model):数据保存

  • 各部分之间的通信方式如下
    1.View 传送指令到 Controller
    2.Controller 完成业务逻辑后,要求 Model 改变状态
    3.Model 将新的数据发送到 View,用户得到反馈

  • 互动模式 - 接受用户指令时,MVC 可以分成两种方式
    1.一种是通过 View 接受指令,传递给 Controller
    2.另外一种是直接通过Controller接受指令。

  • 实例:Backbone 实际项目往往采用更灵活的方式
    1.用户可以向 View 发送指令(DOM 事件),再由 View 直接要求 Model 改变状态。
    2.用户也可以直接向 Controller 发送指令(改变 URL 触发 hashChange 事件),再由 Controller 发送给 View
    3.Controller 非常薄,只起到路由的作用,而 View 非常厚,业务逻辑都部署在 View。所以,Backbone 索性取消了 Controller,只保留一个 Router(路由器) 。

3. MVP模式
  • MVP 模式将 Controller 改名为 Presenter,同时改变了通信方向。
    1.各部分之间的通信,都是双向的。
    2.ViewModel 不发生联系,都通过 Presenter 传递。
    3.View 非常薄,不部署任何业务逻辑,称为"被动视图"(Passive View),即没有任何主动性,而 Presenter非常厚,所有逻辑都部署在那里。
4. MVVM模式
  • MVVM 模式将 Presenter 改名为 ViewModel,基本上与 MVP 模式完全一致。
  • 唯一的区别是,它采用双向绑定(data-binding):View的变动,自动反映在 ViewModel,反之亦然。
  • 相比前两种模式,更加的高效,简洁,操作性和复用性也搞
5. 关于MVVM的优缺点
  • 优点

  • 方便测试
    MVC下,Controller基本是无法测试的,里面混杂了个各种逻辑,而且分散在不同的地方。有了MVVM我们就可以测试里面的ViewModel,来验证我们的处理结果对不对(Xcode7的测试已经越来越完善了)。

  • 便于代码的移植
    比如iOS里面有iPhone版本和iPad版本,除了交互展示不一样外,业务逻辑的Model是一致的。这样,我们就可以以很小的代价去开发另一个App。(以前做公司iPad的时候就深深感觉到,全部在VC里面是多么的痛苦和重新开发一个没有啥区别)。

  • 兼容MVC
    MVVMMVC的一个升级版,目前的MVC也可以很快的转换到MVVM这个模式。VC可以省去一大部分展示逻辑。

  • 缺点
    类会增多,每个VC都附带一个ViewModel,类的数量*2

  • ViewModel会越来越庞大
    我们把逻辑给了ViewModel,那势必Model也会变得很复杂,里面的属性和方法越来越多。可能重写的方法比较多,因为涉及到一些数据的转换以及和Controller之间的通信。

  • 调用复杂度增加
    由于数据都是从ViewModel来,想想突然来了一个新人,一看代码,不知道真实的模型是谁。比如常用Tableview的数据源,一般都是一个数组,如果不断的通过ViewModel去取,沟通上没有那么直接。况且每封一层,意味着要写很多代码去融合他们的转换。

6. 如何理解大前端时代
  • 简单来说,大前端就是所有前端的统称,比如Android、iOS、web、Watch等,最接近用户的那一层也就是UI层,然后将其统一起来,就是大前端。大前端最大的特点在于一次开发,同时适用于所有平台,开发者不用为一个APP需要做Android和iOS两种模式而担心。大前端是web统一的时代,利用web不仅能开发出网站,更可以开发手机端web应用和移动端应用程序。

  • 由于node的出现,前端工程师不需要依赖于后端程序而直接运行,从而前后端分离起来。所以当开发一个新产品的时候服务只需要写一次,但是面向用户的产品可能有很多,例如网站、Android客户端、iOS客户端和微信小程序等。由于各个平台使用的技术栈都不一样,代码无法复用,非常浪费人力、物力。那么有没有什么技术能够解决这一痛点呢?大前端应运而生,其实大前端的主要核心就是跨平台技术,有了跨平台技术,各个平台的差异性就抹平了,开发者只需要一套技术栈就可以开发出适用于多个平台的客户端。

  • 目前的主流跨平台方案:Cordova/phoneGap、React Native、Weex、微信小程序、PWA和Flutter等,根据其原理性,可以分为三大类。
    1.H5+原生(Cordova、Ionic、微信小程序)
    2.JavaScript开发+原生渲染 (React Native、Weex、快应用)
    3.自绘UI+原生(Flutter)
    4.增强版Web App(PWA)
    5.接下来简单介绍这三种跨平台方案。

  • H5+原生混合开发
    这种模式又称为Hybrid开发,现在很多App都用这种模式去开发,常见的有微信、淘宝、美团、爱奇艺等知名移动应用等。国内也有很多公司使用Hybrid模式去开发平台,供开发者使用,像Dcloud、AppCan、Inoic等,基本上都是参考Cordova衍生出的混合开发框架。

  • JavaScript开发+原生渲染

  • 这类开源框架的代表主要是Facebook的React Native、阿里的Weex,当然也有未开源的美团的Picasso,以及最新推出的快应用。

  • JavaScript开发+原生渲染的方式主要优点如下:
    1.采用Web开发技术栈,社区庞大、上手快、开发成本相对较低。
    2.原生渲染,性能相比H5提高很多。
    3.动态化较好,支持热更新。

  • 当然也有缺点如下:
    1.渲染时需要JavaScript和原生之间通信,在有些场景如拖动可能会因为通信频繁导致卡顿。
    2.JavaScript为脚本语言,执行时需要JIT,执行效率和AOT代码仍有差距。
    3.由于渲染依赖原生控件,不同平台的控件需要单独维护,并且当系统更新时,社区控件可能会滞后;除此之外,其控件系统也会受到原生UI系统限制,例如,在Android中,手势冲突消歧规则是固定的,这在使用不同人写的控件嵌套时,手势冲突问题将会变得非常棘手。

7. React Native
  • React Native (简称RN)是Facebook于2015年4月开源的跨平台移动应用开发框架,是Facebook早先开源的JS框架 React 在原生移动应用平台的衍生产物,目前支持iOS和Android两个平台。RN使用Javascript语言,类似于HTML的JSX,以及CSS来开发移动应用,因此熟悉Web前端开发的技术人员只需很少的学习就可以进入移动应用开发领域。

  • React Native的原理和React设计一致,React中虚拟DOM最终会映射为浏览器DOM树,而RN中虚拟DOM会通过 JavaScriptCore 映射为原生控件树。

  • JavaScriptCore 是一个JavaScript解释器,它在React Native中主要有两个作用:
    1.为JavaScript提供运行环境。
    2.是JavaScript与原生应用之间通信的桥梁,作用和JsBridge一样,事实上,在iOS中,很多3.JsBridge的实现都是基于 JavaScriptCore 。

  • 而RN中将虚拟DOM映射为原生控件的过程中分两步:
    1.布局消息传递; 将虚拟DOM布局信息传递给原生
    2.原生根据布局信息通过对应的原生控件渲染控件树
    3.由于React Native是原生控件渲染,所以性能会比混合应用中H5好很多,同时React Native是Web开发技术栈,只需维护一份代码,即可在多个平台上使用。

8. TypeScript
  • TypeScript是 JavaScript 的一个超集,主要提供了类型系统对 ES6 的支持,它由 Microsoft 开发。

  • TypeScript 是 JavaScript 的类型的超集,它可以编译成纯 JavaScript。编译出来的 JavaScript 可以运行在任何浏览器上。TypeScript 编译工具可以运行在任何服务器和任何系统上。TypeScript 是开源的。

  • TypeScript 增加了代码的可读性和可维护性
    1.类型系统实际上是最好的文档,大部分的函数看看类型的定义就可以知道如何使用了
    2.可以在编译阶段就发现大部分错误,这总比在运行时候出错好
    3.增强了编辑器和 IDE 的功能,包括代码补全、接口提示、跳转到定义、重构等

  • TypeScript 非常包容
    1.TypeScript 是 JavaScript 的超集,.js 文件可以直接重命名为 .ts 即可
    2.即使不显式的定义类型,也能够自动做出类型推论
    3.可以定义从简单到复杂的几乎一切类型
    4.即使 TypeScript 编译报错,也可以生成 JavaScript 文件
    5.兼容第三方库,即使第三方库不是用 TypeScript 写的,也可以编写单独的类型文件供 TypeScript 读取

  • TypeScript 拥有活跃的社区
    1.大部分第三方库都有提供给 TypeScript 的类型定义文件。
    2.Google 开发的 Angular2 就是使用 TypeScript 编写的。
    3.TypeScript 拥抱了 ES6 规范,也支持部分 ESNext 草案的规范。

  • TypeScript 的缺点
    1.有一定的学习成本,需要理解接口(Interfaces)、泛型(Generics)、类(Classes)、枚举类型(Enums)等前端工程师可能不是很熟悉的概念。
    2.短期可能会增加一些开发成本,毕竟要多写一些类型的定义,不过对于一个需要长期维护的项目,TypeScript 能够减少其维护成本。
    3.集成到构建流程需要一些工作量。
    4.可能和一些库结合的不是很完美。