MVC、MVP及MVVM之间的关系

半世苍凉 提交于 2019-11-26 19:49:31

1.网页的!DOCTYPE声明及对网页起何作用

 

DOCTYPE是document type(文档类型)的简写,用来说明你用的XHTML或者HTML是什么版本。
其中的DTD(例如上例中的xhtml1-transitional.dtd)叫文档类型定义,里面包含了文档的规则,浏览器就根据你定义的DTD来解释你页面的标识,并展现出来。
要建立符合标准的网页,DOCTYPE声明是必不可少的关键组成部分;除非你的XHTML确定了一个正确的DOCTYPE,否则你的标识和CSS都不会生效。

 

1)<!Doctype>声明位于文档中的最前面,处于<html>标签之前。告知浏览器的解析器,用什么文档类型规范来解析这个文档。

2)严格模式的排版和js运作模式是以该浏览器支持的最高标准运行。
3)在混杂模式中,页面以宽松的向后兼容的方式显示。模拟老式浏览器的行为以防止站点无法工作。
4)DOCTYPE不存在或格式不正确会导致文档以混杂模式呈现。
---------------------

  

2.Webpack底层原理及脚手架工具分析

webpack出现的原因

模块的加载和传输过程中,若每个模块都请求一个,这样会由于请求次数过多,导致启动速度过慢。若是把所有模块打包成一个文件只请求一次,会导致文件太大,每次请求都会消耗很大的流量。最好的方式是把代码块按块区分,按需进行懒加载,按需懒加载就需要对代码块进行静态分析,编译打包,这就是webpack所要做的工作。

webpack的原理

对各个模块之间的依赖关系进行静态分析,然后将这些模块按照一定的规则生成对应的静态资源。

entry: 入口文件, webpack执行构建的第一步将从Entry开始,可抽象成输入
output: 输出结果,再webpack经过一些列处理并得出最终想要的代码后输出结果
module: 模块,在webpcak中一切皆模块,一个模块对应一个文件。webpack会从配置的Entry开始递归找出所有依赖的模块。
loaders: 模块转换器,将不同类型的文件进行处理,例如less、sass文件转换成css,typeScript转换成js
plugin: 扩展插件,在webpack构建过程实现扩展逻辑,来改变构建结果和做我们想要做的事情
chunk: 代码块,一个Chunk由多个模块组合而成,用于代码合并于分割

  

webpack工作流程

webpack启动后会从Entry文件的Module开始构建,递归解析这个Entry依赖的所有Module,每找到一个Module就会根据配置的Loader去找相应的转换规则,对Module进行转换之后,再解析出当前Module依赖的Module。这些Module会以Entry为单位进行分组,一个Entry及其所有依赖的Module被分到一个组也就是一个Chunk。最后,Webpack会将所有的Chunk转换成对应的Bundle文件输出,再整个流程中,Webpack会在恰当时机执行Plugin里定义的逻辑。

关于mainifest.bundle.js

这个文件是最先加载的,负责解析webpack打包的其他bundle文件,使其按要求进行加载和执行。

  

3.ES6中的 Map Set 使用汇总

MAP含义:

ES6提供了Map数据结构,它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值,包括对象都可以当作键。
即,Object结构提供了 字符串-值 的对应,Map结构提供了 值-值 的对应,是一种更完善的Hash结构实现。
Map的数据形式是一个二维数组,一种红黑树的数据结构,键是唯一的。

Map使用上需要警惕的地方

Map对象的键为应用类型的时候,例如键为一个Array对象,在这样的场景下,Map只有对同一个对象的引用,才将其视为同一个键,也就是根据内存来寻址的,例如如下例子,set和get的键表面上是同一个值,但是实际上存放的内存不一样,所以get返回undefined

Set

ES6提供了Set数据结构,它类似于数组,但是存储的元素都是唯一的,这里的唯一指的是他们存储的内存位置是唯一。

Set使用上需要警惕的地方

由于Set中元素的独一无二,根据内存地址来进行判断,所以如果有多个元素是引用型的话,尽管值相同,但是内存地址不同,那么在Set对象中也将会存储多份,和Map类似

ES6中的 Map Set 使用汇总详细了解https://www.jianshu.com/p/563dd154011f

 

4.彻底理解浏览器缓存机制

两个概念

    • 强缓存
      用户发送的请求,直接从客户端缓存中获取,不发送请求到服务器,不与服务器发生交互行为。

    • 协商缓存
      用户发送的请求,发送到服务器后,由服务器判定是否从缓存中获取资源。

    • 两者共同点:客户端获得的数据最后都是从客户端缓存中获得。

    • 两者的区别:从名字就可以看出,强缓存不与服务器交互,而协商缓存则需要与服务器交互。

 

四个过程详解

(a)浏览器判定是否有缓存

(b)缓存是否过期

(c)跟服务器协商是否使用缓存

(d)协商缓存

 

ES6中的 Map Set 使用汇总详细了解:https://www.cnblogs.com/shixiaomiao1122/p/7591556.html

5.理解执行环境、作用域链和活动对象

执行环境

​ 执行环境是JavaScript中最为重要的一个概念。执行函数定义了变量或函数有权访问的其它数据,决定了它们各自的行为。每个执行环境都有一个与之关联的变量对象(variable object)和一个作用域链(scope chain),环境中定义的所以变量和函数都保存在其变量对象中。执行环境分为两种,一种是全局执行环境,一种是函数执行环境。

  1. 全局执行环境

    ​ 全局执行环境是最外围的一个执行环境,其变量对象就是全局活动对象(window activation object),全局执行环境直到应用程序退出——例如关闭网页或浏览器——时才会被销毁。

  2. 函数执行环境

    ​ 每个函数都有自己的执行环境。当执行流进入一个函数时,函数环境就会被推入一个环境栈中。当函数执行完之后,栈将其环境弹出,把控制权返回给之前的执行环境。函数执行环境的变量对象是该函数的活动对象(activation object)。

作用域链

​ 对于每一个执行环境,都会创建一个与之关联的作用域链。每个执行环境的作用域链的前端,始终都是该执行环境的变量对象,对于全局执行环境就相当于window对象,对于函数执行环境就相当于该函数的活动对象;对于全局执行环境,已经是根部,没有后续,对于函数执行环境,其作用域链的后续是该函数对象的[[scope]]属性里的作用域链。

函数对象

​ 在一个函数定义的时候, 会创建一个这个函数对象的[[scope]]属性(内部属性,只有JS引擎可以访问, 但FireFox的几个引擎(SpiderMonkey和Rhino)提供了私有属性__parent__来访问它),并将这个[[scope]]属性指向定义它的作用域链上。 在这里的问题中,因为funcA定义在全局环境, 所以此时的[[scope]]只是指向全局活动对象window active object。

活动对象

​ 在一个函数对象被调用的时候,会创建一个活动对象,首先将该函数的每个形参和实参,都添加为该活动对象的属性和值;将该函数体内显示声明的变量和函数,也添加为该活动的的属性(在刚进入该函数执行环境时,未赋值,所以值为undefined,这个是JS的提前声明机制)。

​ 然后将这个活动对象做为该函数执行环境的作用域链的最前端,并将这个函数对象的[[scope]]属性里作用域链接入到该函数执行环境作用域链的后端.

6.ES6 Promise用法小结

1.什么是Promise

Promise 是异步编程的一种解决方案,其实是一个构造函数,自己身上有all、reject、resolve这几个方法,原型上有then、catch等方法。

Promise对象有以下两个特点。

(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。

(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

更多详细内容:https://www.liaoxuefeng.com/wiki/1022910821149312/1023024413276544

7.MVC、MVP及MVVM之间的关系

概要

MVC、MVP及MVVM都是一种架构模式,为了解决图形界面应用程序复杂性管理问题而产生的应用架构模式。

MVC模式概要

1.即Model、View、Controller即模型、视图、控制器。

  • View:它是提供给用户的操作界面,是程序的外壳;
  • Model:是程序需要操作的数据和信息;
  • Controller:接收View层传递过来的指令,选取Model层对应的数据,进行相应操作。

2.举一个现实中的类似的例子,MVC如同一家商铺的运作模式,View层相当于是这家商铺的店面,Model层相当于这家商铺的仓库,Controller层相当于是这家商铺的执行部门。

3.MVC有如下两种模式,不管哪种模式,MVC的通信都是单向的,由图也可以看出,View层会从Model层拿数据,因此MVC中的View层和Model层还是存在耦合的。

MVP模式概要

1.MVP是从MVC进化而来,即Model、View、Presenter;View和Model同MVC中的M和V,MVP只是将MVC中的Controller变成了Presenter;

2.由上面对MVC的介绍中我们可以得知,MVC中的View层和Model层是存在耦合的,但其实我们不提倡View层与Model层有直接的交互;MVP就是这样一种思想的体现,View层与Model的交互只能通过Presenter;

3.MVP与MVC还有一点不同是,它的通信是双向的,如下图所示,有两个方向:V—>P—>M,M—>P—>V

MVVM模式概要

 1.MVVM是由MVP进化而来,MVVM模式基本上与MVP相同,只是把MVP中的P变成了VM,即ViewModel,

2.MVVM中的数据可以实现双向绑定,即View层数据变化则ViewModel中的数据也随之变化,反之ViewModel中的数据变化,则View层数据也随之变化

3.这里以前端框架VUE举例说明MVVM,当然还有许多有名的框架都用的是MVVM模式;MVVM的好处就是数据驱动,数据变,则页面变,这样就能用简单的代码,实现比较复杂的逻辑操作;因此MVVM框架比较适合逻辑复杂的前端项目,比如一些管理系统等。

1)准备视图层

<p>Hello, {{ name }}!</p>          --View层 --VUE中的单向绑定
<input v-model="name">             --View层 --VUE中的双向绑定

2)准备数据层

data: {
            name: ''               --Model层
        }

至于VM层,VUE框架已封装好,预知详情可阅读廖雪峰的博客

4)得益于MVVM框架,我们此时想改变视图层的<p>标签和<input>标签中的name属性的值,只需要通过如下方式即可,这样页面中就会显示“Jack”的名字,如果不是MVVM框架,我们则需要通过document.getElementById('name').innerHTML = 'jack',这种操作dom节点的方式来改变页面的值。

this.name = 'jack'

  

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!