1,MVVM和 MVC的区别?
答题思路:此题涉及知识点很多,很难说清、说透,因为mvc我们前端程序员自己甚至都没用过。但是恰恰反映了前端这些年从无到有,从有到优的变迁过程,因此沿此思路回答将十分清楚。
Web1时代
在web1.0时代,并没有前端的概念。开发一个web应用多数采用ASP.NET/Java/PHP编写,文件中同时包含了HTML、CSS、JavaScript、C#/Java/PHP代码,系统整体架构可能是这样子的:
这种框架的好处是简单快捷,前后端混为一谈,缺点就是非常难维护
为了让代码更容易维护,便衍生出了MVC开发模式和框架
MVC
MVC即model-view-controller(模型-视图-控制器)是一种分层架构思想,它把复杂的业
务逻辑,抽离为职能单一的小模块,每个模块看似相互独立,其实又各自有相互依赖关系。
优点:保证了模块的智能单一性,方便程序的开发、维护、耦合度低。
不足:这样的模型,在理论上是可行的。但往往在实际开发中,并不会这样操作。因为开发过程并不灵活。例如,一个小小的事件操作,都必须经过这样的一个流程,那么开发就不再便捷了。
既然有缺陷,就会有变革。前端的变化中,似乎少了MVP的这种模式,是因为Angular早早地将MWVM框架模式带入了前端。MVP模式虽然前端开发并不常见,但是在安卓等原生开发中,开发者还是会考虑到它
MVVM
MVVM:即 Model-View-ViewModel,(模型-视图-控制器)它是一种双向数据绑定的模式,用viewModel来建立起model数据层和view视图层的连接,数据改变会影响视图,视图改变会影响数据,这样在ViewModel中就减少了大量DOM操作代码。
MVVM在保持View和Model松耦合的同时,还减少了维护它们关系的代码,使用户专注于业务逻辑,兼顾开发效率和可维护性。
总结:
这两者都是框架模式,它们设计的目标都是为了解决Model和View的耦合问题。
MVC模式出现较早主要应用在后端,在前端领域的早期也有应用,如Backbone.js。它的优点是分层清晰,缺点是数据流混乱,灵活性带来的维护性问题。
MVVM模式在前端领域有广泛应用,它不仅解决MV耦合问题,还同时解决了维护两者映射关系的大量繁杂代码和DOM操作代码,在提高开发效率、可读性同时还保持了优越的性能表现。
2,深拷贝和浅拷贝?
上图
如图所示:
obj2是对obj的浅拷贝,obj2新建了一个对象,但是obj2对象复制的是obj的指针,也就是obj1的堆内存地址,而不是复制对象本身。obj和obj2是共用了内存地址的。
obj3是对obj1的 深拷贝,obj3和obj1不共享内存
概念:
浅拷贝 :只复制指向某个对象的指针,而不复制对象本身,相当于是新建了一个对象,该对象复制了原对象的指针,新旧对象还是共用一个内存块
深拷贝:是新建一个一模一样的对象,该对象与原对象不共享内存,修改新对象也不会影响原对象
简单写一个深拷贝
function deepClone(obj) {
// 判断是不是一个对象 是不是为空
if(typeof obj !== 'object' || obj == null){
// 如果是就返回
return obj
}
var result
// 检测obj是数组还是对象。
obj instanceof Array ? result = [] : result = {}
for(var item in obj){
// hasOwnProperty(名字)方法 是用来检测属性是否为对象的自有属性,如果是,返回true,否者false
if(obj.hasOwnProperty(item)){
result[item] = deepClone(obj[item])
}
}
return result
}
var obj = {
zlc:{
name:'sb',
age:123
},
barin:'none'
}
var obj1 = deepClone(obj)
console.log(obj);
console.log(obj1);
3,实现数组的扁平化?
[1, 2, 3, 4, [ 5, 6 ] ] 变成 [ 1, 2, 3, 4, 5, 6]
自己写了两个实现方式
递归方法
var arr = [1, 2, 3, 4, [5, 6]]
function fun(arr) {
//新数组
var arr2 = []
for (var i = 0; i < arr.length; i++) {
//判断是不是数组
if (Array.isArray(arr[i])) {
// 是就合并
var arr2 = arr2.concat(fun(arr[i]))
} else {
//添加
arr2.push(arr[i])
}
}
return arr2
}
console.log(fun(arr));
用split和tostring方法
function fun(arr) {
//数组转字符串。然后查找,的位置在转为数组
var arr = arr.toString().split(',')
// console.log(arr);
//用map方法,拿到数组里的各个值
var newArr = arr.map(function (item) {
//值=item+item
ietm = +item;
// console.log(ietm);
return ietm
})
return newArr
}
fun(arr)
console.log(fun(arr));
4,this的指向有哪些?
this不是一成不变的,他的指向是根据当前所处的环境而变化的,谁调用就指向谁,this永远指向一个对象
在普通函数中指向调用者如果没有调用者就指向window
在事件函数中this指向的是事件源
在定时器中this指向的是window
在箭头函数中,this的指向是继承父级作用域this的指向--而且不能改变this指向
在严格模式中this指向的是undefined--如果函数调用前.上window,那么this就指向window
在构造函数中this指向的是实例化对象
对象中的this谁调用就指向谁
使用call,apply,bled改变this的指向,指向被改变者
5,ajax + fetch + axios 之间的区别 ?
ajax: 是一种创建交互式网页应用的网页开发技术,Ajax的原理简单来说通过 XmlHttpRequest对象来向服务器发送异步请求,从服务器获得到数据,然后用javaScript来 操作DOM而更新页面
使用ajax:
// 1,实例化xml
var xml = new XMLHttprequest()
// 2,建立连接 调用open方法 开始发送请求
xhr.open('get','url地址',true)
// 3,开始和服务端进行交互,调用send方法
xhr.send()
// 4,注册监听
xhr.onreadystatechange = function () {
判断ajax的状态
if (xhr.readyState === 4) {
判断浏览器的状态
if (xhr.status === 200) {
// 渲染页面
// console.log(xhr.responseText);
var text=JSON.parse(xhr.responseText)
document.body.innerHTML=text[0].name
}
}
}
fetch:是在es6出现的,使用了es6中的promise对象,fetch是基于promise设计的,Fetch的代码结构比起ajax简单多了,参数有点像jQuery ajax。但是,一定记住fetch不是ajax的进一步封装,而是原生js,没有使用XMLHttpRequest对象,他相对于axios需要多一层then方法来调用第一次返回值原型身上的方法进行格式转换