• 前端面试常见问题总结


    问题陈列

    JS相关问题

    • JavaScript原型,原型链 ? 有什么特点?
    每个对象都会在其内部初始化一个属性,就是prototype(原型)。
    当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去prototype里找这个属性,这个prototype又会有自己的prototype,于是就这样一直找下去,也就是我们平时所说的原型链的概念。
    
    • 1
    • 2
    • This对象的理解
    this总是指向函数的直接调用者;
    如果有new关键字,this指向new出来的那个对象;
    
    this的指向问题:
    1.作为对象的属性被调用,this指向该对象
    2.作为普通函数得调用,this总是指向全局对象(通常为window),严格模式下this指向undefined
    3.作为构造器调用,通常情况下this指向被构造函数返回的实例,例外如果构造函数显式的返回一个Object类型的对象,name结构也是只会得到这个对象
    4.call和apply调用
    	动态改变this指向,使用一个指定的this值和单独给出的一个或多个参数来调用一个函数
    	允许为不同的对象分配和调用属于一个对象的函数/方法
    	call()方法:指定的this + 多个参数
    	apply()方法:指定的this + 一个包含多个参数的数组
    5.箭头函数,箭头函数不会创建自己的this,它会从自己的作用域的上一层继承this
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • null,undefined 的区别?
    null 表示一个对象是“没有值”的值,也就是值为“空”;undefined 表示一个变量声明了没有初始化(赋值);
    
    undefined不是一个有效的JSON,而null是;
    
    undefined的类型(typeof)是undefined;null的类型(typeof)是object;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • JS 深浅拷贝
    深拷贝和浅拷贝是只针对引用数据类型,例如:Object和Array;
    浅拷贝只复制指向某个对象的指针而不复制对象本身,新旧对象还是共享同一块内存;
    深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象;
    
    深拷贝方法:
    	1.JSON.parse(JSON.stringify(obj))
    	原理: 用JSON.stringify将对象转成JSON字符串,再用JSON.parse()把字符串解析成对象,一去一来,新的对象产生了,而且对象会开辟新的栈,实现深拷贝。
    	2.递归方法实现深度克隆原理:遍历对象、数组直到里边都是基本数据类型,然后再去复制,就是深度拷贝
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 闭包的概念
    闭包就是能够读取其他函数内部变量的函数,在本质上是函数内部和函数外部链接的桥梁
    
    • 1
    // 经典问题
    var arr = []
    for(var i = 0; i < 10; i++){
        arr[i] = function () {
            console.log(i)
        }
    }
    arr[0](); // 10
    arr[1](); // 10
    arr[2](); // 10
    
    // 利用闭包来解决
    var arr = []
    for(var i = 0; i < 10; i++){
        arr[i] = (function (i) {
            return function () {
                console.log(i);
            }
        })(i)
    }
    arr[0](); // 0
    arr[1](); // 1
    arr[2](); // 2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    闭包处理的还是作用域的问题,解决该问题的方法还可以是利用ES6语法,var声明改成let声明

    浏览器相关问题

    • 前端页面有哪三层构成,分别是什么?作用是什么?
    分成:结构层、表示层、行为层
    
    结构层:由 HTML 或 XHTML之类的标记语言负责创建。标签,也就是那些出现在尖括号里的单词,对网页内容的语义含义做出了描述,但这些标签不包含任何关于如何显示有关内容的信息。例如,P标签表达了这样一种语义:“这是一个文本段。”
    
    表示层:由 CSS 负责创建。 CSS对“如何显示有关内容”的问题做出了回答。
    
    行为层:负责回答“内容应该如何对事件做出反应”这一问题。这是 Javascript 语言和 DOM主宰的领域。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 你知道TCP协议、IP协议、HTTP协议分别在哪一层吗
    TCP协议在传输层,IP协议在网络层,HTTP协议在应用层。
    
    • 1
    • 请说出三种减少网页加载时间的方法
    1.服务器角度
    采取CDN加速,开启gzip压缩,允许使用强缓存或协商缓存,增加服务器带宽
    
    2.客户端角度
    合理组织CSS、JavaScript代码位置,减少DOM操作、添加事件委托,部分操作可设置防抖和节流,对于可预见的操作采取preload或prerender的预加载,对于图片可以懒加载,合并CSS图片(精灵图/雪碧图),减少使用iframe,资源优化打包角度
    
    3.资源优化打包角度
    使用打包工具将Js文件、CSS文件和静态文件进行恰当打包处理。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 什么情况下会遇到跨域问题
    跨域问题来自于浏览器的同源策略,即当协议、域名、端口号任意一个不同时,都会引发跨域问题。
    
    解决方法:jsonp、CORS
    
    • 1
    • 2
    • 3
    • 宏任务和微任务
    宏任务是由宿主发起的(Node、浏览器),而微任务由JavaScript自身发起(JS引擎)。
    
    • 1
    宏任务(macrotask)微任务(microtask)
    发起者Node、浏览器JS引擎
    具体事件1. script (可以理解为外层同步代码)
    2. setTimeout/setInterval
    3. UI rendering/UI事件
    4. postMessage,MessageChannel
    5. setImmediate,I/O(Node.js)
    1. Promise
    2. MutaionObserver
    3. Object.observe(已废弃;Proxy 对象替代)
    4. process.nextTick(Node.js)
    运行顺序后运行先运行
    触发新一轮Tick不会

    其中比较注意的是promise的内部既包含宏任务也包含微任务,promise内部执行为宏任务,then执行为微任务

    HTML相关问题

    • HTML新特性
    1.语义标签
    例如:<header>定义文档头部、<footer>定义文档尾部、<nav>定义文档的导航、<section>定义文档中的节
        
    2.增强型表单
    例如:<search>用于搜索、<tel>定义输入电话号码和字段、<date>选取日期
        
    3.新增表单属性
    例如:placehoder输入框默认提示文字、autofocus规定在页面加载时,域自动获得焦点、required要求输入的内容是否可为空
        
    4.音频<audio src=" ">audio>、视频<video src=" ">video>
        
    5.canvas绘图和SVG
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • webworker认识
    Web Worker的作用就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。这样的好处是,一些计算密集型或高延迟的任务,被 Worker 线程负担了,主线程(通常负责 UI 交互)就会很流畅,不会被阻塞或拖慢。
    
    Worker线程一旦新建成功,就会始终运行,不会被主线程上的活动(比如用户点击按钮、提交表单)打断。这样有利于随时响应主线程的通信。但是,这也造成了 Worker 比较耗费资源,不应该过度使用,而且一旦使用完毕,就应该关闭。
    
    • 1
    • 2
    • 3
    • src与href的区别
    href 是指向网络资源所在位置,建立和当前元素(锚点)或当前文档(链接)之间的链接,用于超链接。
    
    src是指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在位置;在请求src资源时会将其指向的资源下载并应用到文档内,例如js脚本,img图片和frame等元素。
    
    • 1
    • 2
    • 3

    CSS相关问题

    • CSS3有哪些新特性
    border-radius:实现倒角、圆角
    box-shadow:阴影
    text-shadow:字体阴影
    gradient:渐变
    transform:rotate scale skew translate 旋转 缩放 定位 倾斜
    animation:动画
    等等
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • CSS选择器有哪些
    1.id选择器  #id
    
    2.类选择器  .class
    
    3.标签选择器  div
    
    4.相邻选择器 div+p
    
    5.子选择器  div>p
    
    6.后代选择器  div p
    
    7.属性选择器  div[class="main"]
    
    8.伪类选择器  div::hover
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • CSS的盒子模型
    有两种模型:IE盒子模型、标准盒子模型
    	IE盒子模型:content部分包含border和padding
    	标准盒子模型:内容(content)、填充(padding)、边界(margin)、边框(border)
    
    在IE盒子模型中,width 和 height 指的是内容区域+border+padding的宽度和高度。
    在标准盒子模型中,width 和 height 指的是内容区域的宽度和高度。增加内边距、边框和外边距不会影响内容区域的尺寸,但是会增加元素框的总尺寸
    
    CSS3中的box-sizing属性:
    box-sizing:border-box表示盒模型基于IE的盒模型,width和height决定盒模型的content区、padding区和border区。
    box-sizing:content-box表示盒模型基于标准盒模型,width和height只决定盒模型的content区
    box-sizing:inherit表示继承自父元素。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 元素水平垂直居中
    /*已知容器的宽高 设置层的外边距*/
    div {
     position: relative;		/* 相对定位或绝对定位均可 */
     width:500px;
     height:300px;
     top: 50%;
     left: 50%;
     margin: -150px 0 0 -250px;     	/* 外边距为自身宽高的一半 */
    }
     
    /*不知宽高-水平垂直居中 利用 `transform` 属性*/
    div {
     position: absolute;		/* 相对定位或绝对定位均可 */
     width:500px;
     height:300px;
     top: 50%;
     left: 50%;
     transform: translate(-50%, -50%);
    }
     
    /*利用flex布局*/
    div {
     display: flex;
     align-items: center; 		/* 垂直居中 */
     justify-content: center;	/* 水平居中 */
    }
     
    /*让绝对定位的div居中*/
    div {
     position: absolute;
     width: 300px;
     height: 300px;
     margin: auto;
     top: 0;
     left: 0;
     bottom: 0;
     right: 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    VUE相关问题

    • vue生命周期函数
    beforeCreate( 创建前 ) => created(创建后)=> beforeMount(挂在前)=> mounted(挂载后)=> 
    beforeUpdate(数据更新前调用)=> updated(更新后)=> beforeDestroy(实例销毁前)=> destroyed(实例销毁后)
    activated(被 keep-alive 缓存的组件激活时调用)
    decactived(被 keep-alive 缓存的组件停用时调用)
    
    • 1
    • 2
    • 3
    • 4
    • vue响应式原理
    实现mvvm的双向绑定,是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调
    
    • 1
    • vue父子组件的生命周期
    1.加载过程
    父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted
    
    2.子组件更新过程
    父beforeUpdate->子beforeUpdate->子updated->父updated
    
    3.父组件更新过程
    父beforeUpdate->父updated
    
    4.销毁过程
    父beforeDestroy->子beforeDestroy->子destroyed->父destroyed
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • vue组件间通信
    1.props 和 $emit
    父组间通过props向下传递数据给子组件,子组件通过event给父组件发送消息,实际上就是子组件把自己的数据发送给父组件。
    
    2.$attrs 和 $listeners
    祖孙间隔代通过$attrs传递数据,$listeners监听数据的改变
    
    • 1
    • 2
    • 3
    • 4
    • 5
    
    <template>
    	<div>
        <B :messageb="messageb" :messagec="messagec" @getC="getC" @getB="getB" />
      div>
    template>
     
    <script>
    	export default {
        name: 'A',
        data(){
          return {
            messageb:'b', //传递给B的数据
            messagec:'c' //传递给C组件的数据
          }
        },
        methods:{
          //执行B子组件触发的事件
          getB(val){
            console.log('B组件的数据:'+ val) //打印 ‘B组件的数据:b’
          },
          //执行C子组件触发的事件
          getC(val){
            console.log("C组件的数据:" + val) //打印 'C组件的数据:c'
          }
        }
      }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    
    <template>
    	<div>
        <input type="text" v-model="mymessage" @change="chnageHandle()" />
        
        
        <C v-bind="$attrs" v-on="$listeners" />
      div>
    template>
     
    <script>
    	export default {
        name: 'B',
        props:[
          messageb:{ // 获得A组件传递过来的数据:'b'
          	type: String,
          	default: ''
          }
        ],
        methods:{
          chnageHandle(){
            //触发A组件中的事件,把messageb给A组件
            this.$emit('getB',this.messageb)
          }
        }
      }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    
    <template>
    	<div>
     		<input type="text" v-model="$attrs.messagec" @change="changeHandle()">
      	div>
    template>
     
    <script>
    	export default {
        name: 'C',
        data () {
          return {}
        },
        methods:{
          changeHandle(){
            //触发A组件中的事件,把从A得到的数据c还给A组件
            this.$emit('getC',this.$attrs.messagec)
          }
       	}
      }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    3.provide和 inject
    provide 和 inject成对出现,用于父级组件向下传递数据;
    父组件中通过provide来提供变量,然后在子组件中通过inject来注入变量。不论子组件有多深,只要调用了inject那么就可以注入provide中的数据。而不是局限于只能从当前父组件的prop属性来获取数据,只要在父组件的生命周期内,子组件都可以调用。
    
    • 1
    • 2
    • 3
    
    <template>
      <div>
        <son>son>
      div>
    template>
     
    <script>
    	export default {
        name: 'grandparent',
        provide: {
          giveSonMessage:'给子组件的数据',
          giveGrandsonMessage:'给孙组件的数据'
        },
        data(){
          return {}
        }
      }
    script>
     
    
    <template>
      <div>
        <input type="text" v-model="value">
        <grandson>grandson>
      div>
    template>
     
    <script>
    	export default {
        name: 'son',
        inject:['giveSonMessage'], //得到父组件传递过来的数据
        data(){
          return {
            value:this.giveSonMessage
          }
        }
      }
    script>
    
    
    <template>
      <div>
        <input type="text" v-model="value">
      div>
    template>
     
    <script>
    	export default {
        name: 'grandson',
        inject:['giveGrandsonMessage','giveSonMessage'], //得到爷组件传递过来的数据,也能获得爷给父的数据
        data(){
          return {
            value:this.giveGrandsonMessage
          }
        }
      }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    4.vuex处理组件之间的数据交互
    如果业务逻辑复杂,很多组件之间需要同时处理一些公共的数据,这个时候才有上面这一些方法可能不利于项目的维护,vuex的做法就是将这一些公共的数据抽离出来,然后其他组件就可以对这个公共数据进行读写操作,这样达到了解耦的目的
    
    • 1
    • 2

    点赞 评论 收藏 ~~ 留言讨论,如有错误,也希望大家不吝指出。 ~~ 点赞 评论 收藏
  • 相关阅读:
    河流动力学复习
    【Java毕设项目】基于SpringBoot+Vue校园便利平台的设计与实现
    Kafka之Producer网络传输
    SpringBoot的学习要点
    PaddleX数据集规范
    CDB与OA-以T为例子进行分析
    跨进程启动后台服务
    对一个即将上线的网站,如何做一个较完整的Web应用/网站测试?
    Polygon zkEVM——Hermez 2.0简介
    JS多选答题时,选项互斥时的情况
  • 原文地址:https://blog.csdn.net/weixin_49175501/article/details/125896739