2023高频前端面试题(持续更新中...)

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永远指向一个对象
  1. 在普通函数中指向调用者如果没有调用者就指向window

  1. 在事件函数中this指向的是事件源

  1. 在定时器中this指向的是window

  1. 在箭头函数中,this的指向是继承父级作用域this的指向--而且不能改变this指向

  1. 在严格模式中this指向的是undefined--如果函数调用前.上window,那么this就指向window

  1. 在构造函数中this指向的是实例化对象

  1. 对象中的this谁调用就指向谁

  1. 使用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方法来调用第一次返回值原型身上的方法进行格式转换

猜你喜欢

转载自blog.csdn.net/al7lin/article/details/129187797