2020前端面试专题整理

本文主要整理了前端面试中关于Vue的热门话题,涵盖了Vue2到Vue3的主要变化,如配置文件位置调整、命令行工具更新、数据监听方式变化以及Vue3中响应式原理的Proxy使用。还讨论了Vue3体积的减小、创建项目的命令变化及启动命令的更新。此外,文章提及了Vue2和Vue3中双向绑定与Vuex冲突的处理,以及Vue3的响应式原理。Vue3利用Proxy实现了更细粒度的监听,减少了性能开销。文章还涉及虚拟DOM、Diff算法、Vue的生命周期钩子、Vuex、Vue Router、状态管理和前端安全等多个方面,提供了丰富的面试知识点。
摘要由CSDN通过智能技术生成
  1. 全是从网上整理的(狗头保命)

  2. vue3.0 与vue2.0的区别:https://juejin.im/post/6844904128628391944

    1. 目录结构发生变化:
      1. 移除了配置文件目录(config与build文件夹),但是多了env.production与env.development,除了文件位置,实际配置和2.0没有什么不同,没有config文件,跨域配置转移到vue.config文件中,配置方法不变
    2. 部分命令发生变化:
      1. 删除了vue list
    3. 数据监听发生变化:
      1. 2.0用的是object.definePromerty的getter与setter
      2. 3.0使用proxy监听,按需监听,速度加快。
    4. Vue更小:runtime-core体积压缩成了约10kb
    5. 创建命令:
      1. 2.0:vue init webpack project-name
      2. 3.0:vue create project-name
    6. 启动:
      1. 2.0:npm run dev
      2. 3.0:npm run serve
    7.  
  3. 双向绑定与vuex的冲突:

    1. 不允许将vuex的值绑定到组件上,直接使用会报错:have no setter
    2. 解决:
      1. 使用get与set:
      2.  使用watch监听:
  4. vue3.0的响应式原理

    1. 使用proxy代替object.defineproperty,因为proxy可以直接监听对象与数组的变化
    2. 但是Proxy只会代理对象的第一层,Vue3.0是如何处理这个问题的
      1. 判断当前的reflect.get是否为一个obj,如果是,就使用reactive做代理
    3. 检测数组的时候可能多次触发get、set,如何避免该问题?
      1. 可以判断key是否为当前被代理对象target自身属性,也可以判断旧值与新值是否相等,满足条件之一,才可能只需trigger
  5. 虚拟DOM与key值

    1. 什么是虚拟dom:

      1. 是js对象记录dom节点的副本,通过对象的方式表示dom结构,通过一些机制,将多次dom修改的结果一次性更新到页面上,来减少页面渲染次数,减少修改dom的重绘重拍次数,提高渲染性能
      2. 在每次数据变化前,都会把虚拟dom缓存一份,将现在的虚拟dom与缓存的虚拟dom使用diff进行对比,不同的地方就重新渲染,大大的缩减了操作真实dom的性能
      3. 现在前端框架基本要求就是不需手动操作dom,尤雨溪说过:框架给你保证的是,你不需要手动优化的情况下,我依然给你过得去的性能
    2. 修改真实dom:
      1. 生成html结构 =》重绘重排
      2. 虚拟dom:
        1. 生成vnode =》使用diff算法 =》更新必要的dom
    3. 优点:
      1. 跨平台:本质是js对象,可以方便的垮平台操作,比如服务端渲染,uniapp
    4. 缺点:
      1. 首次渲染大量dom,由于多了一层虚拟dom,会比innerHTML慢
    5. key:
      1. 在diff中,当新旧子节点顺序不同的时候,最佳操作应该移动元素位置达到目的
      2. 需要在新旧子节点中保存映射关系,以便能够在旧节点中找到哦啊可以复用的节点
  6. keep-alive:

    1. 对组价进行缓存,当组件切换时不会将组件进行卸载
    2. 狗子函数:
      1. actived:每进入缓存的页面就会触发一次,不像created、mounted只会触发一次
  7. 类数组与数组区别:

    1. 类数组是个对象,具有length属性,但是不具有数组的方法
    2. 常见的类数组:
      1. arguements
      2. document.getElementsByTagName
    3. 类数组如何转换为数组:
      1. Array.property.slice.all
      2. Array.from
      3. Array.prototype.forEach遍历生成新的数组
  8. 浏览器和node的event loop

    1. 首先js是单线程,同一时间只能执行一个任务,那么他是如何做到异步回调的呢
      1. CPU:
        1. 计算机的核心,就像是一个工厂,所有的任务都在其中执行,并且是实时的
      2. 进程:
        1. 代表cpu所能处理的单个任务,就像一个工厂资源有限,只能一个车间运行,其他停止工作,也就是说一个cpu只能进行一个进程,但是可以通过时间片轮调度算法,同时运行多个进程
      3. 线程:
        1. 好比这一个车间的每一个工人,完成同一个任务,共享同一个资源,所以一个进程可以包含多个线程,多个线程共享同一个资源
    2. 浏览器的event loop
      1. js任务分为同步与异步任务,同步任务会在执行栈先执行,异步任务放到任务队列中,等待js引擎线程执行空闲之后才会依次执行异步任务
      2. 先执行宏任务
      3. 如果遇到微任务,就将其添加到任务队列中
      4. 宏任务执行完毕,执行任务队列的微任务
    3. 渲染进程:包含以下线程
      1. GUI渲染线程:
        1. 负责页面的绘制、布局
        2. 页面重绘重排就执行该线程
        3. 与js引擎线程互斥,可能会影响绘制ixaoguo
      2. js引擎线程:
        1. 负责解析执行js相关脚本
      3. 事件触发线程:
        1. 用于控制事件循环
        2. 满足触发条件,执行事件,将回调放入任务队列中
      4. 定时器触发线程:
        1. 执行相关定时任务
        2. 执行完毕后将相关的回调函数交由事件触发线程处理
      5. 异步http请求线程:
        1. 处理http请求
        2. 回调函数给事件触发线程处理
  9. promise

    1. 是异步编程的一种解决方案,每一个异步任务都返回一个promise对象,该对象都可以使用then方法,允许指定的回调函数
    2. 从语法上来说,是一个构造函数
    3. 方法:
      1. then:可以接收构造函数状态处理变化,有两个参数,resolve与reject
        1. then也会返回一个promise对象,可以继续使用.then方法,这样也可以解决回调地狱
      2. all:他接收一个以promise对象组成的数组作为参数,当这个数组的所有promise对象状态变为resolve或者rejected,才会调用then方法
      3. race:也是以promise对象组成的数组作为参数,当数组其中一个promise对象状态为resolve或者rejected,就会调用then方法
    4. 状态:
      1. pending、fulfilled、rejected
    5. 原理:
      1. 构造一个promise实例需要给promise构造函数传入一个函数,传入的函数有两个形参,同时这两个形参都是函数类型的参数,分别为resolve与reject
      2. promise的原型上还有个then方法,then方法就是来指定promise状态改变时确定执行的操作,resolve时执行第一个函数(onFulfilled),reject执行第二个(Onrejected)
      3. 当状态为resolve就不能变为reject
    6. 缺点:
      1. 一旦执行,无法取消
      2. 当处于pending状态,无法得知他进展到哪一步了
      3. 如果不设置回调函数,内部错误无法抛出
    7. 优点:
      1. 解决回调地狱
    8. peomise构造函数是同步执行,then是异步执行
  10. 既然 Vue 通过数据劫持可以精准探测数据在具体dom上的变化,为什么还需要虚拟 DOM diff 呢?

    1. vue初始化的时候会对data的数据进行依赖收集,一旦数据发生变化,响应式就会立马得知,所以vue是一开始就知道是哪个在发生变化了,
    2. 但是vue的响应式(push代表)是一个数据就需要一个watcher,一旦绑定数据细粒度过多就会产生大量的watcher,会带来内存以及依赖追踪的开销,但是细粒度过低的话,就无法精确的探测变化,所以vue使用中等细粒度的方案,在第一时间内检测到组件变化,然后在组件内部使用virtual dom diff获取更细致的差异(pull操作)
  11. 虚拟dom的优缺点

    1. vue通过编译将模板转换为渲染函数,执行一个渲染函数就可以得到一个虚拟dom,虚拟dom提供虚拟节点vnode和对两个新旧vnode进行对比得出差异,diff算法逐层比较,删除,添加操作,以此来更新需要更新的dom,达到减少对dom的操作,提高渲染速度,改善用户体验。
    2. 缺点:
      1. 首次渲染有大量的dom,需要做一层虚拟dom计算,会比innerhtml慢
    3. 优点:
      1. 无需手动操作dom,极大提高开发效率
  12. v-model是如何实现的以及语法糖

    1. 语法糖:
      1. @input是对input输入的一个监听
      2. <input v-model="test">
        <input :value="test" @input="test = $event.target.value">

         

      3. 修饰符:
        1. .lazy:v-model.lazy:按回车触发@change事件(替代了@change事件),但是输入的值为string类型
        2. .number
        3. .trim
      4. 一般使用的元素:
        1. radio
        2. checkbox
        3. select
  13. 单页面与多页面
    1. 单页面:
      1. 一个项目中只有一个html页面,页面跳转只是局部刷新,不会重新加载全部资源
      2. 为什么切换快:因为每次切换时,不需要发送http请求,
      3. 首屏加载慢
      4. https://www.jianshu.com/p/90e95b203be0
  14. 防抖与节流
    1. 防抖:尽管你触发事件,但是我是在触发该事件之后的n秒内执行,如果你在这n秒之内又触发事件,那么就会清楚之前的计时器(核心就是在n秒之内不要再触发该事件,那么我才会执行)
    2. 节流:高频率触发事件,但在n秒内只会执行一次
    3. 使用场景:
      1. 防抖:
        1. 登录、搜索用户点击按钮过快,发送多次请求
        2. 文本编辑器实时保存,当无任何操作后最后一秒保存
        3. 点赞取消点赞,需要获取最后一次操作结果发送给服务器
      2. 节流事件:
        1. 每隔几秒计算播放进度信息
        2. 拖拽:固定时间执行一次,防止高频率触发位置变动
  15. 堆、栈
    1. 基本数据类型保存于栈,值都有固定大小,通过值访问即可
    2. 引用数据是保存于堆的对象,大小不固定,栈内存中存放对象的访问地址指向堆内存中的对象
    3. js不允许直接访问堆的对象,所以实际操作的是对象的引用地址
    4. 堆栈溢出:
      1. 操作系统会自动给每个进程分配最大2M栈空间,如果超过该上限,就会溢出
    5. 什么会导致溢出:
      1. 递归调用:就像你一直往一个空间一直放东西,一直入栈,直到调用结束,才会将地址出栈,同样的,如果你创建一个过大的数组,也会引起堆溢出
  16. 闭包
    1. 概念:两个函数互相嵌套,内部函数可以访问外部函数的变量
    2. 作用:
      1. 可以读取函数内部的变量
      2. 让这些变量的值始终保存在内存中
      3. 闭包就会让js的垃圾回收机制不会回收外部函数所占用的资源,因为外部函数内部嵌套的需要依赖于外部函数的变量
    3. 缺点:
      1. 最严重的问题就是内存泄漏,因为闭包会让函数内的变量都在内存中,导致内存消耗大
    4. 优点:
      1. 避免变量污染到全局
      2. 将变量存储到独立的作用域,作为私有成员使用
    5. GC:
      1. 在js中,如果一个对象不再被引用,就会被回收,如果两个对象互相引用,没有被第三方引用,也会被回收,但是函数a被其内部的b引用,函数b又被函数a外部引用,所以不会被回收
    6. 内存泄漏:
      1. 意外的全局变量,这里的全局指的是window,将变量使用完毕后设置为null
      2. 计时器使用完毕后没有回收
      3. 闭包
    7. 使用场景:
      1. 使用setimeout:
            //原生的setTimeout传递的第一个函数不能带参数
            setTimeout(function(param){
                alert(param)
            },1000)
        
        
            //通过闭包可以实现传参效果
            function func(param){
                return function(){
                    alert(param)
                }
            }
            var f1 = func(1);
            setTimeout(f1,1000);
        
      2. 比如封装一个弹框点击组件:
        1. 点击确定按钮会触发点击相对应的事件,调用接口,如果事件写的是普通函数,那么this指向的是该函数而不是vue,里面方法就不能正常执行,当然也可以在函数外部声明that = this
  17. 箭头函数与普通函数

    1. 箭头函数this:

      1. 没有prototype

      2. 不能修改this指向

      3. 在定义的时候继承他外层的普通函数的this

      4. 如果外部没有普通函数,在严格模式下或者非严格模式都会指向window

  18. 什么是构造函数,他与类的区别

    1. 定义:通过new操作符来调用的,首字符大写,用new生成实例

    2. 创建过程:

      1. 当以new关键字调用时,会新开辟一个内存空间(堆)

      2. 函数体的内部指向该内存

      3. 执行函数体内的代码

      4. 返回该this

    3. es6:class

      1. 他的绝大部分功能es5都可以做到
      2. 类中定义方法不需要加function,可以被子类继承的方法定义在类的prototype中

        // es5
        function Person (name , age){
            this.name = name;
            this.age = age
        }
        Person.prototype.saying = function(){
            return 'im saying '
        }
        
        
        // es6
        class Person (){
            construcotr(name , age){
                this.name = name ;
                this.age = age
            }
        
            saying(){
                return 'im saying'
           }
        }
      3. 类中的内部所有定义的方法都是不可枚举的(not enumerable)

        1. 枚举:对象的属性是否可以遍历出来
          1. 在js中,基本数据类型原型上的属性是not enumberable

          2. 类和模块内部默认采用严格模式

          3. 子类继承了父类之后,必须在constructor中调用super方法,否则不能新建实例

            1. 因为子类没有属于自己的this对象,而是继承了父类的this对象

  19. 改变this指向问题:

    1. this指向的是最后调用他的对象
    2. new关键字改变this指向
    3. 存储this到变量中
    4. 上下文调用:当第一个参数为null或者undefined,this指向window
      1. call

      2. apply

      3. bind:先是创建一个新的函数,与被调用的函数有着相同的函数体,必须得调用,否则只是单一的绑定了而已

        var Person = {
            name: "zhangsan",
            age: 19
        }
        
        function aa(x, y) {
            console.log(x + "," + y);
            console.log(this);
            console.log(this.name);
        
        }
        
        aa.bind(Person, 4, 5); //只是更改了this指向,没有输出
        aa.bind(Person, 4, 5)(); //this指向Person--4,5  Person{}对象  zhangsan
        
      4. call与apply区别:参数不同,apply第二个参数为数组

  20. addEventListener(事件 , 函数处理 , boolean)

    1. 事件是click、mouseLeave

    2. 当事件发生时所需要调用的函数

    3. true或者false,指定为事件捕获还是事件冒泡,默认false,使用冒泡

    4. 移除:removeEventListener

  21. 事件阶段:

    1. 捕获阶段:从根节点到目标节点,途中经过各个dom节点,触发事件

    2. 目标阶段:事件到达目标节点,就到了目标阶段,触发事件

    3. 冒泡阶段:事件在目标节点触发,一层层向上,直到根节点

    4. 阻止:e.stopProgation()

  22. obj方法:

    1. Object.assign:将所有可枚举属性值复制到目标对象,如果是相同属性名,后面的会覆盖前面的值(浅拷贝)

    2. Object.create:创建一个新对象

    3. Object.entry:将对象的每个键值对作为数组的每一项

      let obj = {
          name:"张三",
          sex:"男",
          age:20,
          height:150
      }
       
      for ( let val of Object.entries(obj)){
          console.log(val)
      }
       
      // (2) ["name", "张三"]
      // (2) ["sex", "男"]
      // (2) ["age", 20]
      // (2) ["height", 150]
    4. Object.keys:返回一个由对象的属性组成的可枚举数组

    5. Object.values:返回一个对象的属性值组成的可枚举的数组

  23. for in for of区别:

    1. for in :(遍历索引)

      1. 遍历对象的话返回对象的key值,遍历数组返回数组的下标

      2. 还会遍历到原型上的key值与手动添加的键值

      3. 遍历对象原型上可枚举属性

        1. 可以通过asOwnProperty判断

  24. type mull === object

    1. 不同的对象在底层都用二进制表示,在js中,二进制前三位都为0的话会判断为object类型,null的二进制全为0,前三位自然为0

    2. 110:布尔类型

    3. 100:string

    4. 1:整型,数据是31位带符号整数

    5. typeof Nan  === number

      1. nan:s1111 11111 1111

  25. 什么是实例对象,实例对象和函数对象的区别

  26. js中判断数据类型的方式有哪些,都有什么区别

    1. typeof :判断基础类型

    2. instanceof:判断一个实例属于哪种引用类型

      1. instanceof是根据给定对象实例的原型链去判断的,他会判断给定的instanceof后面的构造函数的prototpe属性是否出现在这个实例原型链还是那个,如果出现了,为true

      2. 只能用来判断对象和函数,不能用来判断字符串和数字等。判断它是否为字符串和数字时,只会返回false

    3. Object.prototype.toString.call()

      1. toString是Object原型对象上的一个方法,这方法会返回调用着的具体类型,也就是toString this指向的对象类型,返回的类型格式为【object array(还包括其他类型)】

  27. 实现链式调用:

    1. function Person (){}
      Person.prototype.say = function(params){
          console.log(params)
          return this
      }
      Person.say('第一次调用').say('第二次调用')

       

  28. Vue 为什么要用 vm.$set() 解决对象新增属性不能响应的问题 ?你能说说如下代码的实现原理么

    1. vue2.0使用obejcy,defineproperty实现数据双向绑定
    2. 在vue实例初始化时候,对属性进行了get set转化
    3. 所以属性必须要刚开始的存在于data里,才能进行响应式操作
    4. 所以就造成了vue无法检测到vue的添加或者删除
    5. 如果目标数据是数组,会直接用数组的splice触发响应式
      1. 反之如果是对象,会先判断属性是否存在,对象是否是响应式的
      2. 最终如果要对对象进行响应式处理,就使用defineReactive进行响应式处理
  29. 说一下 Vuex 的原理以及自己的理解 

    1. vuex是一个采用集中式管理vue状态的管理模式
    2. 包含state、mutations、actions、module、getter
    3. state:存储数据的,可以用this.$store.state来访问,为响应式的
    4. mutations:更改state的方法
    5. getter:可以认为是store的计算属性,他的返回值会随着他的依赖存储起来,当依赖值发生变化而随之发生变化
    6. actions:可以写任意的异步操作,来触发mutations从而改变state
    7. module:将store分割成模块,每个模块都包含state、mutation、getter、actions
    8. 我们在组件中触发的动作,一般都是想改变数据啥的,但是在vuex中,数据是集中进行管理的,我们不能直接去修改state里面的数据,所以会把这个动作commit到mutation中
    9. 然后mutations改变state的数据
    10. 在组件中使用$dispatch去触发actions的方法
    11. 为什么要用vuex:
      1. 因为比如说对于多层嵌套组件,传参就会比较复杂,不像父子组件通信稍微简单一些,而且后期代码也不好维护,所以就需要把组件共享的状态给抽离出来,统一管理,并且让任何一个组价都可以使用,这样就会让代码变得更加结构化更加容易管理!!!!
  30. v-model语法糖:
    1. 当在input中使用v-model其实是触发了元素的@input事件嘛,
    2. 通过v-bind将父组件的数据绑定到了子组件的props属性中,然后就通过$emit触发父组件元素的$input事件
  31. vue虚拟dom 以及diff 算法

    1. 真实dom渲染流程:
      1. 先根据html元素生成一个dom树
      2. 再根据样式生成页面的样式表
      3. 再将dom树与样式表联合起来,形成render树
      4. 浏览器根据render树再进行布局
    2. js操作真实dom的代价:
      1. 用js或者jquery操作dom,浏览器会把生成的dom树从开始到结尾执行一遍,如果我们要执行操作多个dom节点,浏览器会收到第一个dom操作请求,会马上执行流程一遍,但是还会执行对此重复的操作
    3. 为什么要虚拟dom,优点是什么?
      1. 虚拟dom可以理解为是dom的js副本
      2. 如果是要更新几十个dom节点的话,虚拟dom不会立即更新dom,会将这几十次变化先保存到一个js对象,然后再统一更新到dom上,
      3. 页面的更新先全部更新在虚拟dom上,操作内存中的js对象速度要快一些,等更新完成后,将最终的js对象映射到真正的虚拟dom上,浏览器再去重绘重排
    4. diff算法:
      1. 通过对树节点的同层节点进行对比
      2. 特点:
        1. 只会同级比较,不会垮层级比较
      3. 每次diff都会调用updateChildren方法来比较,然后一层层递归下去,直到将oldVnode与newVnode对比完,每次找到相同节点,都会一层一层往下比较他们的子节点,是一个逐渐深入的递归遍历过程
  32. keep-alive:
    1. include:字符串、数组、正则匹配缓存组件
    2. exclude:字符串、数组、正则匹配不被缓存组件
    3. max:数字,最多缓存多少组件实例
  33. computed与普通属性区别:
    1. 是基于依赖进行缓存的,当相关依赖发生变化,就会重新计算,并进行缓存
    2. computed是响应式的,method不是
    3. computed定义就像属性一样访问就ok了,method需要调用
    4. computed不支持异步,监听不到数据变化
    5. 购物侧结算价格
  34. vuex与localstore区别
    1. vuex存储在内存
    2. localStorage存储在本地,并且只能存储
    3. 应用场景:
      1. localStorage一般在跨页面传递数据使用
      2. vuex可以是响应式的,local不能
    4. 永久性:
      1. 刷新页面时vuex存储的值会丢失,local不会
  35. vue-router原理:
    1. 更新视图但是不重新请求页面
    2. 默认是hash模式,使用window.addEventListener('hasChange' ,callback,false)对浏览器的地址进行监听,当调用push时,将新路由添加到浏览器访问历史的栈顶,使用replace时,将栈顶的路由换成新路由
    3. hsitory模式:使用window.onpopstate对浏览器地址进行监听,有pushstate()与replacestate()方法,但是该方法需要服务端来辅助配合,避免url无法匹配到资源时能够返回页面,不然空白咋整。
  36. vue data某一个属性值发生改变后,视图会立即同步并且执行渲染吗?
    1. 不会,vue实现响应式会按照一定的策略进行dom更新的,
    2. 在更新dom时是异步执行的,只要侦听到数据变化,vue开启一个队列,如果同一个watcher被监听,就会被推入到一个队列中,然后去除重复数据,对于不必要的计算还是非常重要的,
  37. object.definedProperty缺点:
    1. 无法监听原生数组
    2. 必须遍历对象的每个属性
    3. 如果属性是对象,还得进行深度遍历
  38. proxy:
    1. 支持监听原生数组
    2. 可以对新添加的属性进行监听
  39. vue hook:
    1. 使用场景:需要在父组件上知道子组件什么时候被创建、更新啥的,一般情况下我们可以使用@monuted
      <parent-component>
        <child-component @hook:mounted="handleChildMounted"></child-component>
      </parent-component>
      1. 但是在第三方组件中,根本不好使
    2. 可以使用@hook在父组件中监听子组件的@hook:created函数,不需要在子组件中再$emit
  40. 动态路由:
    1. 场景:比如说商品详情页,需要传商品id
    2. 主要是使用path属性,使用动态参数,可以是this.$route.params获取到动态参数
  41. 为什么子组件不可以直接修改父组件数据:
    1. 为了维护父子组件的单向数据流
    2. 每次父组件更新数据了,子组件中所有的prop都会刷新,这是为了防止意外的改变父组件状态,可能导致数据流混乱,如果破坏了单向数据流,当系统比较复杂,维护成本就会比较高
    3. 只能通过$emit定义事件,父组件修改数据
  42. html5新特性,如何解决兼容h5新标签?如何区分html与h5?
    1. 新特性:
      1. 语义化标签:header、footer、nav
      2. 音频:audio、video
      3. 画布:canvas
      4. 地理:geolocation
      5. 拖拽释放:drag and drop
      6. localstorage(本地离线存储):浏览器关闭数据不丢失
      7. sessionstorage:浏览器关闭数据丢失
      8. 表单控件:calendar、date、time
    2. 兼容:
      1. 使用html5shiv插件
    3. 区分:
      1. 文档声明:
        1. h5:<!doctype html>
      2. 结构化语义:
        1. html:div
        2. h5:header
  43. b标签与strong标签区别:
    1. b:为了加粗而加粗
    2. strong:为了标明重点而加粗
  44. AMD、CMD、commonJS
    1.  commonjs:同步加载node服务端
      1. 一个文件就是一个模块,拥有独立的作用域,普通方式定义的变量、函数等都属于该模块
      2. 通过require加载模块
      3. 通过export与module.exports暴露模块
      4. 注意:
        1. 当exports和module.export同时存在,后者会覆盖前者
        2. 不会污染全局,因为都有独立作用域
    2. AMD:异步加载模块(浏览器端模块化开发规范)依赖前置
      1. 使用require进行模块化,通过require(' ' , function(){})加载
      2. defined进行声明
    3. CMD:js模块化 依赖延迟
  45. 回调函数与任务队列区别:
    1. 回调函数:作为参数传递给一个函数,在一个函数执行完成后执行
    2. 任务队列:是一个事件队列
      1. 同步任务:主线程上排队执行的任务,前一个执行完才能执行下一个
      2. 异步任务:进入任务队列,当主线程的任务执行完毕后,开始异步执行
  46. js内置对象:
    1. encodeURL()
    2. eval()将string作为js代码执行
    3. isFinite()是否为无限数,参数首先会转换为一个数值
    4. parseInt()
  47. h5兼容问题:

    1. fastclick:移动端设备上的网页点击有300ms延迟
      1. 来源:ios为了能够将pc端网页展示在iphone,添加了双击缩放功能
      2. 原因:浏览器需要判断是否为双击
      3. 解决:使用fastclick
    2. 播放视频不会全屏:
      1. webket-playsinline = ‘true’
    3. opacity为c3属性,只有部分浏览器支持
      1. 使用私有前缀开头
    4. ios端滑动不流畅:
      1. -webkit-overflow-scrolling:touch:让滚动条产生滚动回弹效果
    5. ios上拉下拉出现白色空白
        created () {
          document.body.addEventListener('touchmove', (e) => {
            if (e._isScroller) return;
            e.preventDefault()
          }, {
            passive: false
          })
        },
      
      1. ios中,手指下拉会触发touchmove事件,该事件触发的是webview容器,所以容器会拖动剩下空白
      2. 解决:监听事件禁止滑动
    6. 移动端点击穿透:
      1. 产生条件:
        1. 上面的元素触发点击事件,随即隐藏
        2. 下面的具有点击特性的元素也会触发click
      2. 使用fastclick并js初始化
  48. css兼容:
    1. ie6使用margin:0 auto无法居中,父元素设置textalign:center
  49. opacity与visibity、display
    1. opacity:不会改变布局,但是会触发事件
    2. vibisity:不会改变布局,会触发事件
    3. display:从页面中删除
  50. 移动端1px:transform:scale(0.5)
  51. 居中:
    1. display:table
      1. vertical-align:middile,text-align:center
    2. 已知高宽
      1. absolute,50%减去自身高宽
      2. absolute,上下左右0,margin:auto
    3. 未知高宽:
      1. absolute,left:-50%,right:-50%,trnasoform:transliate(-50%,-50%)
    4. flex,justify-content:center,align-item:center
  52. 盒模型:
    1. 标准模型:box-sizing:content-box,宽高不包括内边距、边框
    2. 怪异模式:box-sizing:border-box
  53. 清除浮动:
    1. 父盒子:
      1. over-flow:hidden
      2. height
      3. after微元素清除法
    2. 在最后一个浮动元素后添加clear:both
  54. 塌陷:父盒子随着子盒子的margin-top一起往下
    1. 父盒子:
      1. border
      2. padding-top
      3. over-flow:hidden
      4. float
  55. 栅格化原理:
    1. 比如ant的row与col,将一行分为24份,那col是几就占几分,底层是按百分比实现,结合媒体查询,实现响应式
  56. 原型链:
    1. 对象都有原型对象,每一个原型对象又是一个对象,都有他的原型,那么这样环环相扣,形成连式结构 ,最终指向null
  57. commonjs与es6模块引入区别:
    1. commonjs:相当于一个拷贝,如果导出一个值,内部修改是不会影响到他的
    2. es6是动态引用,不会缓存,
  58. axios与fetch区别:
    1. axios:
      1. 是对xhr的封装,是一个基于promise的用于浏览器
      2. 特点:
        1. 可以使用promise方法
        2. 可以使用并发请求:axios.all
        3. 可以取消请求:cancelToken
        4. 自动转换json数据
    2. fetch:
      1. 语法更加简洁
      2. 但是只对网络请求报错
  59. 地址栏输入url到加载完成
    1. 浏览器会根据给出的url交给dns域名解析,找到对应ip,再向服务器发请求
    2. 然后服务器再向后台处理请求,返回数据啥的,浏览器再接受文件
    3. 浏览器再对接受到的资源进行解析吧,形成dom树啥的
    4. 再渲染页面
    5. https://juejin.im/post/6844903807286001677
  60. 前端安全:
    1. XSS:
      1. 恶意往web页面写html代码,比如我们做一个留言功能,别人在留言板里写js代码,窃取用户浏览器存储的信息等
      2. 解决:
        <meta http-equiv="Content-Security-Policy" content="form-action 'self';">
        1. 使用meta标签
        2. 前后端对一些页面元素做过滤检查,过滤掉<>、style样式等

        3. 禁止使用内敛样式

    2. CSRF:跨域请求伪造
      1. 攻击者引诱用户进入第三方网站,然后在第三方网站中,向需要攻击的网站请求,因为用户已经在第三方登录过,,所以就可以直接获取信息向攻击网站操作,冒充用户身份
      2. 解决:
        1. 使用token验证,
          1. 服务端给前端一个token,保存到session中
          2. 前端也保存到本地,提交表单携带token
          3. 如果token不一致话,就拒绝请求
    3. sql注入:
      1. 页面与数据库交互使用sql语句,假如使用drop table啥的sql
      2. 解决:
        1. 限制输入长度
        2. 输入校验
        3. 过滤掉sql的特殊字符 '' 、'' ''
  61. 布局:
    1. 百分比布局(流式布局)
      1. 高度不变,宽度自适应
      2. 在pad横屏下,宽度被拉长,页面被拉伸很多
    2. 媒体查询:
      1. 设置几个分区,但是要设计出多个方案
    3. rem布局:
      1. 使用js或者media根据html值改变font-size值
  62. BFC:
    1. 相当于一个盒子,内部的布局不会影响外部
    2. 如何形成:
      1. overflow不是visibl
      2. float不是none
      3. position为ab或者fixed
    3. 作用:
      1. 清除浮动
      2. 防止垂直margin合并
        1. 比如说垂直排列的两个div都有margin,那么上面的margin-bottom与下面的margin-top会合并,取两者最大值作为margin
        2. 解决:为一个元素添加div,设置Overflow-hidden
  63. js设计模式:
    1. 单例模式
    2. 观察者模式:只要被观察者数据发生变化就做出一些操作
  64. 从输入url到显示资源步骤 :
    1. 客户端 先检查本地有没有对应的ip地址,如果有就返回,反之请求上级dns服务器,直到找到根节点
    2. 客户端再向服务端发送连接请求(tcp)
      1. 客户端带有一个syn的标志数据包给服务器,在一定的时间内等待接收回复
      2. 接收到数据包之后,返回一个带有syn、ack标志的数据包来确认信息
      3. 客户端收到后发送一个ack数据包来表示握手成功
    3. 客户端 发送http请求
    4. 服务器响应请求,查找资源,并返回响应报文与资源
    5. 客户端先渲染dom树,再添加css样式与js脚本啥的,最终渲染到页面
  65. vue的data为什么是个函数
    1. obj是引用数据类型,如果不是函数,那么多个组件实例data都指向的是同一个地址,修改一个,影响其他
    2. data是函数,就会有自己的单独作用域
  66. vue的key:
    1. 在vue中,我们无需直接操作dom,操作数据来改变视图,背后使用了diff算法
    2. 用key给每个节点做个唯一标识
    3. 作用就是高效更新虚拟dom,diff算法可以识别到该节点,找到正确位置插入新节点
  67. vue 单页面应用首屏加载卡顿如何解决:

    1. 关闭vueconfig的productionsoucemap为false(为了调试看源码使用的)

    2. 路由懒加载

      1. require(‘@/component’)

    3. 使用cdn加快请求速度

      1. 比如有时候服务器不稳定啥的

      2. 打包时间太长、体积过大啥的

      3. 去掉不必要的console

      4. 可以使用骨架屏

  68. vue的seo:

    1. prerender-spa-plugin

  69. vuex:
    1. 场景
      1. 兄弟组件
      2. 需要共享的数据信息
    2. 缺点:
      1. 每次刷新之后state数据初始化,可以存储于localstorage,或者使用vuex-along
  70. 数据更新视图不更新,原因是什么,如何解决?
    1. 在vue中,只有在data数据初始化里的值才是可以响应式的
    2. 数组操作:
      1. 数组使用一些方法是无法检测变动:
        1. slice方法是会返回一个新数组,不会修改原数组
    3. 对象属性添加:vue.set、this.$set
    4. 动态改变数据很慢啥的:this.$forceupdate()
    5. 或者使用Obejct.assign 将可枚举的值从一个或者多个源头复制到目标对象,返回新对象
  71. get与post区别:
    1. 传送方式:
      1. get:url
      2. post:报文传输
    2. 传送长度:
      1. get:受限于url的长度限制
      2. post:无限制
    3. get产生一个tcp数据包,post产生两个tcp数据包
      1. get:浏览器会把浏览器的http header与data一起发送出去,然后服务器响应200
      2. post:浏览器会先发送header,服务器响应100,然后浏览器发送data,服务器响应200
    4. 安全性get要差一些,一般涉及到用户信息密码啥的都,但是一般查询数据啥的都可以用get
    5. get在回退时是可以的,但是post会再次请求
    6. get请求会被浏览器保存到历史记录里,但是post不会
  72. settimeout为啥不准:
    1. 因为js是单线程,会先执行主线程任务,再执行任务队列
  73. vue性能优化:
    1. 可以通过代码、项目打包、项目部署来优化
    2. 代码:
      1. 在组件初始化时,使用v-if 来控制组件  在首次使用渲染 减少初始化渲染
        1. 比如说我在做这个政权项目的时候,有时候页面操作很多dialog,然后在页面初始化的时候如果将那么多的dialog都同时渲染,那肯定会影响到性能的呀
      2. 如果有大量的不需要响应式的数据,可以使用object.freeze冻结,提高初次渲染速度
      3. 图片大小、懒加载
        1. 使用image-webpack-loader,在webpack中配置
        2. 懒加载也可以使用vue-lazyload,在main中配置
      4. 组件库按需引入:
        1. elementui就可以,使用babel-pluin,先安装插件,在 babelrc配置一下
  74. nextTick使用场景:
    1. 在created中获取渲染后的dom
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值