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.View
与Model
不发生联系,都通过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
MVVM
是MVC
的一个升级版,目前的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.可能和一些库结合的不是很完美。