90%的面试问题(前端)

发布时间 2023-12-21 19:53:33作者: Y~~~

1.什么是MVVM,MVC模型

  1. MVC框架(Model-View-Controller,模型-视图-控制器):

  • Model(模型):代表数据和业务逻辑,负责数据的存储和处理。

  • View(视图):是用户界面的表示,通常是UI元素,例如网页、图形用户界面等。

  • Controller(控制器):是Model和View之间的协调者,负责处理用户输入、更新Model和通知View更新。

  1. MVVM框架(Model-View-ViewModel,模型-视图-视图模型):

  • Model(模型):与MVC中的Model相同,代表数据和业务逻辑。

  • View(视图):与MVC中的View相同,是用户界面的表示。

  • ViewModel(视图模型):是连接Model和View的桥梁,它有两个方向:一是将Model转化成View,即将后端传递的数据转化成所看到的页面;二是将View转化成Model,即将所看到的页面转化成后端的数据。

总的来说,MVVM和MVC的主要区别在于MVVM中的ViewModel对Model和View进行了抽象,使得UI和业务逻辑分离。

2.vue双向绑定的原理

在Vue中,当初始化数据时,会对数据进行递归遍历,把每一个属性都转换成getter和setter。通过Object.defineProperty()方法实现数据劫持,当数据变化时,会触发setter,setter会通知所有订阅者,订阅者就会更新页面视图,从而实现了数据双向绑定。

当数据模型发生变化时,Vue会自动更新渲染视图;而当用户交互引起视图发生变化时,Vue会自动更新数据模型,从而实现了数据双向绑定。

总的来说,Vue的双向绑定机制通过对数据的劫持,实现了数据与视图之间的同步更新,提高了开发效率和可维护性。

3、分别阐述vue2和vue3的生命周期

Vue 2 和 Vue 3 的生命周期在某些方面是相似的,但在其他方面则有所不同。以下是两个版本的生命周期的详细阐述:

Vue 2 的生命周期

在 Vue 2 中,一个组件的生命周期通常包括以下阶段:

  1. 创建阶段:包括 beforeCreate 和 created 两个生命周期钩子。在这个阶段,组件实例化并初始化数据、属性和方法等。

  2. 挂载阶段:包括 beforeMount 和 mounted 两个生命周期钩子。在这个阶段,组件将模板编译成虚拟 DOM,并将虚拟 DOM 挂载到真实 DOM 上。

  3. 更新阶段:包括 beforeUpdate 和 updated 两个生命周期钩子。在这个阶段,组件的数据会发生变化,Vue 会重新计算虚拟 DOM 与真实 DOM 的差异,并更新 DOM。

  4. 销毁阶段:包括 beforeDestroy 和 destroyed 两个生命周期钩子。在这个阶段,Vue 销毁组件实例并解除其所有的事件监听器和子组件。

Vue 3 的生命周期

在 Vue 3 中,由于使用了 Composition API 和 Options API 的混合,生命周期的钩子函数和结构发生了一些变化。以下是 Vue 3 组件的生命周期概述:

  1. 创建阶段

    • 使用 setup 函数和 Composition API(如 refreactive 等)来初始化数据、属性和方法。

    • onMounted 钩子在组件挂载后立即调用。

  2. 挂载阶段

    • onMounted 钩子负责将组件挂载到 DOM 上。

  3. 更新阶段

    • 当组件的数据发生变化时,Vue 会重新计算虚拟 DOM 与真实 DOM 的差异,并更新 DOM。

    • onUpdated 钩子在更新完成后调用。

  4. 销毁阶段

    • onUnmounted 钩子负责在组件卸载后执行清理操作(如取消网络请求、清除计时器等)。

    • 注意:Vue 3 没有提供直接的 beforeDestroydestroyed 钩子,但你可以使用 onUnmounted 来替代。

不带setup

beforeDestroy=beforeUnmounted

destory=unmounted

监听

捕获错误errorCaptured

捕获render:renderTracked、renderTriggered

使用keep-alive

activated 插入

deactivated移除

当组件实例在服务器上被渲染之前要完成的异步函数:serverPrefetch

 

总结来说,Vue 3 的生命周期更加依赖于 Composition API 和新的生命周期钩子,这使得代码组织更加灵活和可维护。然而,这需要开发者适应新的 API 和模式,以便充分利用 Vue 3 的新功能和性能优化。

 

4.v-if和v-show有什么区别

v-show只是简单地控制元素的display属性,而v-if是条件渲染,条件为真时,元素被渲染,条件为假时,元素被销毁。

 

5.async和await是什么?有什么作用?

async和await是es7的语法,作用就是ansync声明一个function是异步的,而await等待一个一部方法完成。很好替代promise的then。

async语法返回一个promise对象,一但遇到await就会先返回。

 

6.常用的数组方法有哪些

  1. join(连接字符):将数组中的元素通过给定的连接字符连成一个字符串。

  2. push(值/变量):从数组的末尾向数组添加元素。

  3. pop():从数组的末尾删除元素,一次只删除一个,返回的是被删除的元素。

  4. shift():从数组的首部删除元素。

  5. unshift(值/变量):从数组的首部插入元素。

  6. sort():排序函数。默认的是从小到大。若需要降序排序,需要自己写比较函数。

  7. reverse():将数组元素颠倒顺序。

  8. concat():连接两个或多个数组。

  9. slice():切片函数:从原数组中截取部分元素组成新的数组。

slice和substring接收的是起始位置和结束位置(不包括结束位置),而substr接收的则是起始位置和所要返回的字符串长度。

 

7.数组有哪几种循环方式分别有什么作用?

1.*every()**方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值。

2.fi1ter()*方法创建一个新数组,其包含通过所提供函政实现的测试的所有元素。

3.foreach 方法对数组的每个元素执行一次提供的函数。

4.some()**方法测试是否至少有一个元素可以通过被提供的函数方法,该方法返回一个Boolean类型的值。

 

8、常用的字符串方法

  1. charAt()方法从一个字符串中返回指定的字符。

  2. concat()方法将一个或多个字符串与原字符串连接合并,形成一个新的字符串并返回。

  3. include()方法用于判断一个字符串是否包含在另一个字符串中,根据清况返回true或false。

  4. indexof()方法返回调用它的ssring.对象中第一次出现的指定值的索引。

  5. match()方法检索返回一个字符串匹配正则表达式的的结果。

  6. padstar()方法用另一个字符串填充当前字符串(重复,如果需要的话),以便产生的字将串达到给定的长度

  7. replace()方法返回一个由替换值。

  8. slice()方法提取某个字符串的一部分,并返回一个新的字符串,且不会改动原字符串。

  9. split()“方法使用指定的分隔符字符串将一个string对象分割成字符串数组,以将字符串分隔为子字符串,以确定每个拆分的位置。

  10. trim()方法会从一个字符串的两端删除空白字符。

 

9.什么是原型链?

new 一个function方法时候,打印出来会有prototype属性,这个指向它本身,prototype有proto属性又指向构造函数原型对象。

 

10.什么是闭包?手写一个闭包函数

闭包就是在一个function的方法内部也有一个function并且能访问到其内部变量

function a(){
var a=1;
function b(){
console.log(a)
}
return b;
}
let c=a()

闭包可以设置为私有变量,可以延长作用域,但是会造成内存泄漏。

 

11.常用的继承有哪些?

  1. 原型链继承:

    特点:1、实例可继承的属性有:实例的构造函数的属性,父类构造函数属性,父类原型的属性。(新实例不会继承父类实例的属性!

    缺点:1、新实例无法向父类构造函数传参。2、继承单一。3、所有新实例都会共享父类实例的属性。(原型上的属性是共享的,一个实例修改了原型属性,另一个实例的原型属性也会被修改!)。

     

    2.构造函数继承:call,apply

    特点:1、只继承了父类构造函数的属性,没有继承父类原型的属性。2、解决了原型链继承缺点1、2、3.3、可以继承多个构造函数属性(call多个)。4、在子实例中可向父实例传参。

    缺点:1、只能继承父类构造函数的属性。2、无法实现构造函数的复用。(每次用每次都要重新调用)3、每个新实例都有父类构造函数的副本,臃肿。

 

3.组合继承。

4.原型继承式:重点:用一个函数包装一个对象,然后返回这个的数的调用,这个函数就变成了个可以随意增添属性的实例或对象。object.create()就是这个原理。特点:类似于复制一个对象,用函数来包装。缺点:1、所有实例都会继承原型上的同性。2、无法实现复用。(新实例属性都是后面添加的)。

5.class继承:通过extend和super

12.后台管理中权限管理如何实现?

登录:当用户填写完账号和密码后向服务端验证是否正确,验证通过之后,服务端会返回一个token,拿到token之后(我会将这个token存贮到cookie中,保证刷新页面后能记住用户登录状态),前端会根据token再去拉取一个user_info的接口来获取用户的详细信息(如用户权限,用户名等等信息)。权限验证:通过token获取用户对应的权限,动态根据用户的权眼算出其对应有权眼的路由,通过router.addRoutes 动态挂载这些路由。

具体思路:

登录成功后,服务端会返回一个token(该token的是一个能唯一标示用户身份的一个key),之后我们将token存储在本地cookie之中,这样下次打开页面或者刷新页面的时候能记住用户的登录状态,不用再去登录页面重新登录了。

ps:为了保证安全性,我同现在后台所有token有效明(Expires/Max-Age)都是Session,就是当浏览晶关闭了就丢失了。重新打开游览器都需要重新登录验证,后端也会在每周固定一个时间点重新刷新token,让后台用户全部重新登录一次,确保后台用户不会因为电脑遗失或者其它原因被人随意使用账号。

用户登录成功之后,我们会在全局钩子router.beforefach 中拦戴路由,判断是否已获得token,在获得token之后我们就要去获取用户的基本信息了

页面会先从 cookie中查看是否存有token,没有,就走一遍上一部分的流程重新登录,如果有token,就会把这个token 返给后端去拉取user_info,保证用户信息是最新的。当然如果是做了单点登录得功能的话,用户信息存储在本地也是可以的。当你一台电脑登录时,另一台会被提下线,所以总会重新登录获取最新的内容。

先说一说我权限控制的主体思路,前端会有一份路由表,它表示了每一个路由可访问的权限,当用户登录之后,通过token获取用户的role,动态根据用户的role算出其对应有权限的路由,再通过router.addsoutes动态捷载路由。但这些控制都只是页面级的,说白了前端再怎么做权限控制都不是绝对安全的,后端的权限验证是逃不掉的。

使用vuex管理:具体如下:

创建vue实例的时候将vue-router挂载,但这个时候vue-router挂载一些登录或者不用权限的公用的页面。

当用户登录后,获取用role,将role和路由表每个页面的需要的权限作比较,生成最终用户可访问的路由表。

调用router.addRoutes(store.getters.addRouters)添加用户可访问的路由.

14.es6有哪些特性?

let和const具有块级作用域,不存在变量提升的问题。新增了箭头函数,简化了定义函数的写法,同时可以巧用箭头函数的this、(注意箭头函数本身没有this,它的this职决于外部的环境),新增了promise解决了回调地域的问题,新增了模块化、利用import、export来实现导入、导出。新增了结构赋值,ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。新增了class类的慨念,它类似于对象。

15.v-for循环为什么一定要绑定key?

页面上的标签都对应具体的虚拟dom对象(虚拟dom就是js对象),循环中,如果没有唯一key,页面上删除一条标签,由于并不知道删除的是那一条!所以要把全部虚拟dom重新渲染,如果知道key为x标签被删除掉,只需要把渲染的dom为x的标签去掉即可

 

16.组件中的data为什么要定义一个函数而不是一个对象?

每个组件都是Vue的实例。组件共享data属性,当data为引用其他类型的值时,改变其中一当data的值是同一个会影响到其他。

 

17.常见盒子居中方法:

flex,定位,块元素

18.平时怎么解决跨域问题的?

在Web开发中,跨域问题是一个常见的挑战。跨域问题指的是在浏览器中,当一个网页的JavaScript代码尝试访问不同域名、不同端口或不同协议的资源时,浏览器为了安全考虑会阻止这种跨域请求。

以下是一些常用的方法来解决跨域问题:

  1. JSONP (JSON with Padding):JSONP是一种利用<script>标签的src属性可以跨域访问的特性来实现跨域请求的方法。它通过在服务器上动态生成一个JavaScript函数调用,以实现跨域数据的传输。但是,JSONP只支持GET请求,并且需要服务器端支持JSONP。

  1. CORS(Cross-Origin Resource Sharing):CORS是一种基于HTTP头部的机制,它允许服务器声明哪些源(域名、协议、端口)的请求可以获得资源的访问权限。在服务器端设置合适的CORS响应头,例如Access-Control-Allow-Origin,可以让浏览器绕过跨域限制。

  1. 代理服务器:可以设置一个代理服务器,将浏览器的请求发送到同一域名下的服务器,然后由代理服务器转发请求到目标域名上。代理服务器可以在后端进行跨域请求,然后将结果返回给前端。

  1. WebSocket:WebSocket是一种基于TCP的协议,它允许在不同域名下建立持久的双向通信连接。通过WebSocket建立连接后,可以在客户端和服务器之间传输数据,绕过跨域限制。

  1. 使用后端服务:可以将跨域请求的逻辑放在后端服务器上,然后通过与后端服务器进行通信来获取数据。前端向自己的服务器发送请求,再由服务器转发请求到目标服务器上,并将结果返回给前端。这种方式可以避免浏览器的跨域限制。

请注意,具体使用哪种方法解决跨域问题取决于你的应用需求和架构。每种方法都有自己的优缺点,选择适合你项目的解决方案是非常重要的。

19.cookie,localstorage,sessionstorage有什么区别?

Cookie、LocalStorage和SessionStorage是在Web开发中用于在浏览器端存储数据的三种常见方式,它们之间有以下区别:

  1. 存储容量:Cookie的存储容量较小,通常为4KB左右。LocalStorage和SessionStorage的存储容量较大,通常为5MB或更多。

  1. 生命周期:Cookie具有过期时间,可以在设置的过期时间之前一直存在于浏览器中。LocalStorage的数据没有过期时间,除非被手动清除。SessionStorage的数据在浏览器会话结束时清除,即当用户关闭浏览器窗口时。

  1. 数据与服务器的交互:Cookie在每个HTTP请求中都会被发送到服务器,包括对同一域名下的所有请求。LocalStorage和SessionStorage的数据仅在浏览器端存储,不会自动发送到服务器。

  1. 访问权限:Cookie可以设置为具有域名和路径限制,以控制哪些请求可以访问它们。LocalStorage和SessionStorage只与创建它们的页面相关,同一域名下的其他页面无法直接访问存储在其中的数据。

  1. API接口:Cookie的操作需要使用document.cookie API进行读取和设置。LocalStorage和SessionStorage分别提供了localStoragesessionStorage对象作为API接口,可以通过这些对象进行数据的读取、设置和删除。

总体而言,Cookie适用于在客户端和服务器之间传递数据,而LocalStorage和SessionStorage更适合在浏览器端存储和获取临时数据或用户偏好设置。选择使用哪种存储方式取决于你的需求和数据的特性。

20.this的指向有哪些?

1。普酒函数中的this指向windows

2、定时器中的thi指向windove 3、箭头经数没有this,它的this指向取决于外部环境

4、事件中的this脂向事件的A用者。

5、构造读数中this和原型对象中的this,都是指向构造函数new出来实例对象

6、类class中者的this 指向由constructor构造器nevw出来的实例对象

7.、自调用函数中的this指向window

 

21.什么是递归,递归有哪些优缺点?

递归:如果一个函数在内部可以调用其本身,那么这个函数就是递归函数。简单理解:函数内部自己调用自己,这个街数就是递归函数。

优点:结构清断、可读性强。

缺点:效率低、调用栈可能会溢出,其交每一次函数资用会在内存栈中分配空间。而每个进程的栈的容量是有限的,当调用的层次太多时,就会超出栈的容量,从而导致栈溢出。

 

22.谈谈平时用了哪些方法优化

减少http请求次数、打包压缩上线代码、使用懒加载、使用雪碧图、动态渲染组件,CDN加或包。

23.vue是挂在到哪个标签上的

vue实例最后会挂载在body标签里面,所以我们在vue中是获取不了body标签的,如果要使用body标签的话需要用原生的方式获取。

24.什么是深拷贝,什么是浅拷贝?

浅拷贝:创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。

深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即发生深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。拷贝前后两个对象互不影响。

25.js的运行机制是怎么样的?

js是一个单线程、异步、非阻塞I/O模型、 event loop事件循环的执行机制

所有任务可以分成两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous) .同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务。异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。

阻塞(Blocking)

阻塞模型是传统的编程模型,它意味着一个操作需要完成才能继续执行下一个操作。例如,如果你有一个需要从磁盘读取大量数据的操作,这个操作可能需要花费一些时间。在阻塞模型中,这个操作会阻止其他代码的执行,直到它完成。这意味着其他代码必须等待这个操作完成才能执行。

在JavaScript中,由于其单线程的特性,阻塞模型可能会导致性能问题。例如,如果你有一个需要长时间运行的循环或操作,它会阻止JavaScript引擎处理其他代码,导致界面响应变慢。

非阻塞(Non-blocking)

非阻塞模型是为了解决阻塞模型的问题而设计的。在非阻塞模型中,长时间运行的操作不会阻止其他代码的执行。相反,这些操作会在后台运行,而其他代码可以继续执行。

在JavaScript中,非阻塞模型主要通过异步编程实现。异步编程是一种处理长时间运行的操作而不阻塞其他代码的方法。例如,你可以使用setTimeoutsetIntervalPromiseasync/await等JavaScript特性来实现异步编程。

总的来说,阻塞和非阻塞的主要区别在于它们如何处理长时间运行的操作。阻塞模型会阻止其他代码的执行,而非阻塞模型则允许其他代码在长时间运行的操作完成之前继续执行。在JavaScript中,由于其单线程的特性,非阻塞模型是更常见的编程模型,因为它可以避免性能问题并提高用户体验。

 

26.请写至少三种数组去重的方法?(原生js)

//利用filter
function unique(arr) {
   return arr.fi1ter(function(item,index,arr) {
       //当前元素,在原始数组中的第一个索引==当前索引值,否则返回当前元素
       return arr.indexof(item,0)=n= index;
      );
       var arr = [1,1, 'true' , 'true ' ,true,true,15,15,fa1se,fa1se,undefined , undefined,nu11 , nu11,NaN,NaN, 'NaN',o,o,'a', 'a',(],03];
       console.log(unique(arr))
       
//利用ES6 set去重(ES6中最常用)
function unique (arr) {
   return Array.from(new set(arr))}
var arr = [1,1,'true' , 'true' ,true,true, 15,15 ,fa1se,false,undefined , undefined,nu11, nu11,NaN,NaN, ' NaN',o,o,'a','a',{,];
console.log(unique(arr))
//[1,"true", true,15,false,undefined,nu11,NaN,“NaN",o,"a"",0,0]
//利用for嵌套for,然后splice去重(ESS中最常用)
function unique(arr){
   for(var i=0; i<arr.length; i++){
       for(var j=i+l;j<arr.length; j++){
           if(arr[i]=-arr[j]){
               //第一个等同于第二个.splice方法删除第二个
               arr.splice(j,1);
               j--;
              }
          }
      }
   return arr;}
var arr =[1,1, 'true' ,'true ' ,true,true,15,15,fa1se,false,undefined, undefined,nu11,nu11,NaN,NaN, 'NaN',0,0, 'a''a',0,];
console. log(unique(arr))
//[1,"true",15,fa1se,undefined,NaN,NaN,“NaN","a",..},...3]//NaN和门没有去重,两个nu11直接消失了
               

27.请写出至少两种数组排序方法(原生js)

// 快速排序
function quicksort(elements){
   if(elements . 1ength <=1){
       return elements;
      }
   var pivotIndex=Math.floor(elements.length/ 2);
   var pivot=elements.splice(pivotIndex,1)[0];
   var left=[];
   var right=[];
   for(var i=0;i<elements . length;i++){
       if(elements[i]<pivot){
           left.push(elements[i]);
          }else{
          right.push(elements[i])
          }
          }
          return quicksort(left).concat([pivot] ,quicksort(right));
          return quicksort(left).concat([pivot] ,quicksort(right));
// concat()方法用于连接两个或者多个数组:该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。
}
var elements=[3,5,6,8,2,4,7,9,1,10];
document.write(quicksort(elements));
//插入排序
function sort(elements){
//假设第0个元素是一个有序数列,第1个以后的是无序数列,//所以从第1个元素开始将无序数列的元素插入到有序数列中去for (var i =1; i<=elements . 1ength; i++) {
1/升序
if(elements[i]< elements[i-1]){
//取出无序数列中的第i个作为被插入元素var guard=elements[i];
//记住有序数列的最后一个位置,并且将有序数列的位置扩大一个var j=i-1;
elements[i]=elements[j];/ /比大小;找到被插入元素所在位置
while (j>=O && guard <elements[j]){
elements[j+1]=elements[j];
j--;
)
elements[j+1]=guard;//插入
)
}
)
var elements=[3,5,6,8,2,4,7,9,1,10];document.write("没调用之前: '+elements);document.write( "<br>');
sort(elements) ;
document.write("被调用之后:'+elements);
//冒泡排序
function sort(elements){
for(var i=0 ;i<elements. length-1;i++){
for(var j=0 ;j<elements.length-1-i;j++){
if(elements[j] > elements[j+1]){
var swap=elements[j];
elements[j]=elements[j+1];elements[j+1]=swap;
)
})
}
var elements=[3,5,6,8,2,4,7,9,1,10];console.log( 'before '+elements);
sort(elements);
console.log( 'after '+elements);

28、知道loadash吗?它有哪些常见API

Lodash是一个一致性、模块化、高性能的JavaScript实用工具库。

_.cloneDeep 深度拷贝 _.reject 根据条件去除某个元素。 _.drop(array, [n=1])作用:将array中的前n个元素去掉,然后返回剩余的部分.

29、http请求方式有哪些

get.post.put、delete等

30、平时用什么工具打包?babel是什么?

WebPack是一个模块打包工具,你可以使用WebPack管理你的模块依赖,并编绎输出模块们所需的静态文件。它能够很好地管理、打包Web开发中所用到的HTML、Javascript、CSS以及各种静态文件(图片、字体等),让开发过程更加高效。对于不同类型的资源,webpack有对应的模块加载器。webpack模块打包器会分析模块间的依赖关系,最后生成了优化且合并后的静态资源。

babel可以帮助我们转换一些当前浏览器不支持的语法,它会把这些语法转换为低版本的语法以便浏览器识别。

31、谈谈set,map

set是es6提供的一种新的数据结构,它类似于数组,但是成员的值都是唯一的。

map是es6提供的一种新的数据结构,它类似于对象,也是键值对的集合,但是键的范围不仅限于字符串,各种类型的值都可以当做键。也就是说,Object结构提供了"字符串一值"的对应,Map结构提供了"值一值""的对应,是一种更完善的Hash结构实现。如果你需要"键值对"的数据结构,Map比 Object更合适.。

32.清楚浮动方法有哪些

为什么要清除浮动,因为浮动的盒子脱离标准流,如果父盒子没有设置高度的话,下面的盒子就会撑上来。

1.额外标签法(在最后一个浮动标签后,新加一个标签,给其设置clear: both; )(不推荐)

2.父级添加overflow属性(父元素添加overflow:hidden)(不推荐)

3.使用after伪元素清除浮动(推荐使用)

33、常见的布局方法有哪些

页面布局常用的方法有浮动、定位、flex、grid网格布局、栅格系统布局 浮动: ·优点:兼容性好。 ·缺点:浮动会脱离标准文档流,因此要清除浮动。我们解决好这个问题即可。绝对定位 ·优点:快捷。 ·缺点:导致子元素也脱离了标准文档流,可实用性差。flex布局(CSS3中出现的) ·优点:解决上面两个方法的不足,flex布局比较完美。移动端基本用flex布局。网格布局(grid) .CSS3中引入的布局,很好用。代码量简化了很多。 利用网格布局实现的一个左右300px中间自适应的布局

34.图片懒加载如何实现的?

就是我们先设置图片的data-set属性(当然也可以是其他任意的,只要不会发送http请求就行了,作用就是为了存取值)值为其图片路径,由于不是src,所以不会发送http请求。然后我们计算出页面 scrollTop的高度和浏览器的高度之和,如果图片距离页面顶端的坐标Y(相对于整个页面,而不是浏览器窗口)小于前两者之和,就说明图片就要显示出来了(合适的时机,当然也可以是其他情况),这时候我们再将data-set属性替换为src属性即可。

35.vue中的computed和watch的区别是什么?

computed计算属性就是为了简化template里面模版字符串的计算复杂度、防止模版太过冗余。它具有缓存特性 computed用来监控自己定义的变量,该变量不在data里面声明,直接在computed里面定义,然后就可以在页面上进行双向数据绑定展示出结果或者用作其他处理; watch主要用于监控vue实例的变化,它监控的变量当然必须在data里面声明才可以,它可以监控一个变量,也可以是一个对象,一般用于监控路由、input输入框的值特殊处理等等,它比较适合的场景是一个数据影响多个数据,它不具有缓存性 watch:监测的是属性值,只要属性值发生变化,其都会触发执行回调函数来执行一系列操作。computed:监测的是依赖值,依赖值不变的情况下其会直接读取缓存进行复用,变化的情况下才会重新计算。

36.什么vuex ,谈谈你对它的理解?

1.首先vuex的出现是为了解决web组件化开发的过程中,各组件之间传值的复杂和混乱的问题2将我们在多个组件中需要共享的数据放到store中, 3.要获取或格式化数据需要使用getters, 4.改变store中的数据,使用mutation,但是只能包含同步的操作,在具体组件里面调用的方式 this. $store. commit('xxxx ')

  1. Action也是改变store中的数据,不过是提交的mutation,并且可以包含异步操作,在组件中的调用方式this.$store.dispatch('xxx');在actions里面使用的commit(调用mutation')

37、数据类型的判断方法有哪些,优点和缺点?

typeof:简单;只能检测基本类型

instanceof:能检查引用类型;不能检测基本类型且不支持跨iframe

object.prototype.toString.call 检出所有类型;ie6以下undefined和null为object

38.知道symbol吗

es6停入新的原始类型symbol,表示独一无二的值。

39.请描述一下ES6中的class类

es6中的class可以把它看成是es5中构造函数的语法糖,它简化了构造函数的写法,类的共有属性放到constructor里面 1.通过class关键字创建类,类名我们还是习惯性定义首字母大写。

⒉类里面有个constructor函数,可以接受传递过来的参数,同时返回实例对象 3.constructor函数只要new生成实例时,就会自动调用这个函数,如果我们不写这个函数,类也会自动生成这个函数 4.多个函数方法之间不需要添加逗号分隔5.生成实例new不能省略 6.语法规范,创建类类名后面不要加小括号,生成实例类名后面加小括号,构造函数不需要加function 1.继承中,如果实例化子类输出一个方法.先看子类有没有这个方法,如果有就先执行子类的 ⒉.继承中,如果子类里面没有,就去查找父类有没有这个方法,如果有,就执行父类的这个方法(就近原则) 3.如果子类想要继承父类的方法,同时在自己内部扩展自己的方法,利用super调用父类的构造函数,super必须在子类this之前调用 7.时刻注意this的指向问题,类里面的共有的属性和方法一定要加this使用. 1.constructor中的this指向的是new出来的实例对象 2.自定义的方法,一般也指向的new出来的实例对象

3.绑定事件之后this指向的就是触发事件的事件源 4.在ES6中类没有变量提升,所以必须先定义类,才能通过类实例化对象

40、谈谈盒子模型

在标准盒子模型中,width和height指的是内容区域的宽度和高度。增加内边距、边框和外边距不会影响内容区域的尺寸,但是会增加元素框的总尺寸。

41.promis是什么作用?

Promise是异步编程的一种解决方案.简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise是一个对象,可以从改对象获取异步操作的消息。 它可以解决回调地狱的问题,也就是异步深层嵌套问题 .catch() ·获取异常信息.finally() ·成功与否都会执行(不是正式标准)

promise.all

promise.race

42.箭头函数有哪些特征,请简单描述一下它?

箭头函数没有自己的this,this指向定义箭头函数时所处的外部执行环境的this即时调用call/apply/bind也无法改变箭头函数的this 箭头函数本身没有名字 箭头函数不能new,会报错 箭头函数没有arguments,在箭头函数内访问这个变量访问的是外部执行环境的arguments箭头函数没有prototype

43.移动端有哪些问题怎么解决

点击事件30OMS延迟问题解决方案:下载fastclick的包

H5页面窗口自动调整到设备宽度,并禁止用户缩放页面

<meta name="viewport" content="width=device-width,initia1-scale=1.0,minimum-scale=1.0,maximum-scale=1.0, user-scalable=no">

忽略Android平台中对邮箱地址的识别

<meta name="format-detection" content="emai1=no">

当网站添加到主屏幕快速启动方式,可隐藏地址栏,仅针对ios的safari <! -- ios7.0版本以后,safari上已看不到效果-->

 
<meta name="apple-mobile-web-app-capable" content="yes ">

44.一个页面输入url到页面上加载显示完成,这个过程发生了什么?

01.浏览器查找域名对应的IP地址(DNS查询:浏览器缓存->系统缓存->路由器缓存->ISP DNS缓存->根域名服务器) 02.浏览器向Web服务器发送一个HTTP请求(TCP三次握手) 03.服务器301重定向(从http:/lexample.com重定向到 http://www.example.com)04.浏|览器跟踪重定向地址,请求另一个带 www的网址 05.服务器处理请求(通过路由读取资源) 06.服务器返回一个HTTP响应(报头中把Content-type 设置为'text/htm')07.浏览器进DOM树构建 08.浏览器发送请求获取嵌在HTML中的资源(如图片、音频、视频、CSS、JS等) 09.浏览器显示完成页面 10.浏览器发送异步请求

45.安全问题:CSRF 和XSS攻击?

CSRF:利用A本身漏洞,去请求A的api。http-only

Xss:外部链接。token

46.cookie和session区别

  • 1、 cookie数据存放在客户的汶览器上,session数据放在服务器上。 2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗 。考虑到安全应当使用session. ·3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能 。考虑到减轻服务器性能方面。应当使用COOKIE. 4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie.5、所以个人建议: 1。将登陆信息等重要信息存放为SESSION 2。其他信息如果需要保留,可以放在COOKIE中