前端面试整理(第一篇)

最近在看前端面试题,一直相信自己整理过印象才会更加深刻,对一些知识点的理解不能只停留在表面的1234几点,需要进行扩展。 最近的面试经历更让我了解到自己的不足
changeLog:
9.18 vue问题由7个添加到30个

一.基础

HTML
  1. 新元素

    • 语义化标签nav, article, aside, header,footer
    • canvas
    • Audio、video
    • 地理位置
    • input校验
CSS
  1. css新元素

    • 选择器
    • 动画
    • 过渡
    • transform
    • 弹性盒模型
    • 媒体查询 @media
    • 渐变 inear-gradients
    • 背景
    • 边框
  2. 实现左右固定宽,中间自适应

    .wrap {
      		 width: 200px;
           height: 200px;
           border: 1px solid red;
           position: relative;
    }
    /*1.已知元素高下使用定位+负margin*/
    .box1 {
      background-color: pink;
      position: absolute;
      top: 50%;
      left: 50%;
      margin-top: -50px;
      margin-left: -50px;
    }
    
  3. rem与em区别

    rem是根据根的font-size变化, 而em是根据父级的font-size变化

  4. css权重

    行内1000、id选择器100、类、属性选择器10, 伪类选择器、元素名1

    以上面的权重值为基础, 叠加计算权重。

    伪类选择器:after, before, first-letter, first-line, selection

    • 当同样的元素写多次时,以最下面的为准,即css样式会覆盖
    • 与元素‘挨得近’的规则生效, 比如在html中定义了规则,在css中也定义了规则, 则html中的规则生效
    /*html中*/
    <style type="text/css">
    h1 {
      padding:10px;
    }
    </style>
    
    /*css中*/
    h1 {
      padding: 5px;
    }
    
    • 通配符权重为0
    • !important权重最高,但也会被权重更高的!important覆盖
JS

es6

  • let、const、var的区别
    let相当于var,用于声明变量,在块级作用域内有效,不能重复声明,不会变量提升,不会预处理
    const: 用于定义常量,不可修改,其他特点等同于let, 用于保存不用改变的数据
  • map与普通对象的区别
    普通对象只能用字符串当作键,而es6中的map数据结构,类似于对象,也是键值对的集合,但是键的范围不限于字符串,各种类型的值(包括对象)都可以当作键
  • 常用es6语法
    箭头函数,模板字符串、变量解构赋值等

跨域

  • jsonp跨域
    通过script标签引入js文件,这个js文件又会返回一个js函数调用,也就是请求后通过callback方式回传结果

    缺点:只支持get请求
    优点:
    1.不受同源策略限制
    2.兼容性更好
    3.支持老版本浏览器

  • cors跨域

    使用自定义的http头部请求。让浏览器与服务器之间进行沟通,从而决定请求或相应是否成功
    优点:
    1.支持所有类型的http请求
    2.比jsonp有更好的错误处理机制
    3.被大多数浏览器支持

  • h5的postMessage方法
    h5新特性,目前只支持窗口(iframe)之间交换数据, 不能和服务端交换

  1. ajax了解
    客户端发起请求,获取或发送服务端数据的一项技术
    优势
    -无刷新页面
    -服务器端任务转到客户端处理
    -减轻浏览器负担节约带宽
    -彻底将页面与数据分离

    缺点
    -无法使用回退按钮
    -不利于网页seo
    -不能发送跨域请求

  2. 闭包
    嵌套函数引用了外部函数变量的函数叫做闭包。可能会造成变量污染

  3. window.location对象包括哪些属性
    hash、host、hostname、href、origin、pathname、search、protocol

  4. 手写ajax实现过程

  5. 轮播图实现原理概述

    一系列的大小相等的图片平铺,利用CSS布局只显示一张图片,其余隐藏。通过计算偏移量利用定时器实现自动播放,或通过手动点击事件切换图片

  6. this的指向

    this永远指向最后调用它的那个对象

    Tips:改变this指向的方法:

    • 使用es6的箭头函数,箭头函数的this始终指向函数定义时的this、而非执行时
    • 函数内部使用_this=this
    • 使用apply、call、bind
    • new实例化一个对象
  7. 严格模式

引自阮一峰老师博客详解严格模式

严格模式是ES5中提出的运行模式,其目的为下面几个

  • 消除js语法的一些不合理、不严谨之处,减少一些怪异行为;
  • 消除代码运行的不安全之处,保证代码运行安全
  • 提高编译器效率,增加运行速度
  • 为未来新版本的js做好铺垫

调用:

<script>
"use strict";  // 必须放在第一行
</script>

// 针对函数
function strict(){
  "use strict";
  return "这是严格模式"
}

规定:

  • 全局变量必须显示声明
  • 禁止使用with语句
  • 创设eval作用域。正常模式下,eval语句的作用域,取决于它处于全局作用域,还是处于函数作用域。严格模式下,eval语句本身就是一个作用域,不再能够生成全局变量了,它所生成的变量只能用于eval内部。
   "use strict";
  var x = 2;
  console.info(eval("var x = 5; x")); // 5
  console.info(x); // 2
  • 禁止this关键字指向全局对象
  • 禁止在函数内部遍历调用栈
  • 禁止删除变量,只有configurable设置为true的对象属性,才能被删除
  "use strict";
  var x;
  delete x; // 语法错误
  var o = Object.create(null, {'x': {
      value: 1,
      configurable: true
  }});
  delete o.x; // 删除成功
  • 对一个对象只读属性赋值报错
  • 对一个getter方法读取的属性赋值报错
  • 对禁止扩展的对象添加新属性报错
  • 删除不可删除的属性报错
  • 对象不能有重名属性
  • 函数不能有重名参数
  • 禁止八进制表示法 如var n=0100;
  • 不允许对arguments赋值;
  • arguments不再追踪参数变化
  function f(a) {
    a = 2;
    return [a, arguments[0]];
  }
  f(1); // 正常模式为[2,2]
  function f(a) {
    "use strict";
    a = 2;
    return [a, arguments[0]];
  }
  f(1); // 严格模式为[2,1]
  • 禁止使用arguments.callee
  • 函数必须声明在顶层
  • 也就是说,不允许在非函数的代码块内声明函数
  1. bind、call、apply区别

    apply()方法调用一个函数,其具有一个指定this值,以及作为一个数组(或类似数组的对象)提供的参数

    call()方法接受的是若干个参数列表,而apply接收的是一个包含多个参数的数组

    bind()方法创建一个新的函数,然后传入this所绑定的值和参数

    var a ={
            name : "Cherry",
            fn : function (a,b) {
                console.log( a + b)
            }
    }
    
    var b = a.fn;
    b.apply(a,[1,2])    // 3
    b.call(a,1,2)       // 3
    b.bind(a,1,2)()     // 3
    

二.框架

VUE
  1. 组件传值
    -父传子: props
    -子传父:on+$emit传递
    -父子双向:on.sync
    -子孙之间:通过一个中间文件作为媒介,子组件传值到中间文件,父组件从中间文件获取,避免逐级获取
    -兄弟:event|vuex

  2. vue生命周期

    创建、挂载、更新、销毁(几个钩子函数)

    首先创建实例,执行init,init过程中先调用beforeCreate,然后在injections 和reactivity时,再去调用created,要修改data数据的话最早也得在created里面去做

    created完成后,它会判断实例里是否含有el选项,没有的话会调用vm.$mount(el)方法,然后执行下一步,有的话会将模版解析成模版函数来编译模板

    render函数是发生在beforeMount和mounted之间的,当执行完render函数后会调用mounted,mounted挂载结束后 实例就算走完流程。

    更新和销毁一般是外部触发的

  3. 常用vue指令

    v-if v-show、v-for、v-on、v-bind、v-slot、v-model

  4. V-show、v-if区别, 应用场景

    v-if是‘真正’的条件渲染,当满足条件时才会销魂和重建

    v-show无论初始条件是什么 元素总会被渲染,只是机遇css进行切换

    在性能消耗方面: v-if 有更高的切换消耗,v-show有更高的初始渲染消耗

    所以,如果需要频繁切换,使用v-show, 如果运行时条件很少改变使用v-if

    • 对于管理系统的权限列表来说, 使用v-if会避免渲染不该出现的权限
    • 前台页面的数据展示推荐使用v-show
  5. vuex原理

    vuex是一个状态管理容器, 数据的流向是单向数据流,数据并不具有持久化特性,默认刷新就重置所有状态

    里边的数据及方法与vue对比来看

  6. vue双向绑定如何实现?用了什么模式

    vue数据双向绑定是通过数据劫持结合发布-订阅者模式的方式来实现,
    流程图如下:

    我们已经知道实现数据的双向绑定,首先要对数据进行劫持监听,所以我们需要设置一个监听器Observer,用来监听所有属性。如果属性发上变化了,就需要告诉订阅者Watcher看是否需要更新。因为订阅者是有很多个,所以我们需要有一个消息订阅器Dep来专门收集这些订阅者,然后在监听器Observer和订阅者Watcher之间进行统一管理的。接着,我们还需要有一个指令解析器Compile,对每个节点元素进行扫描和解析,将相关指令对应初始化成一个订阅者Watcher,并替换模板数据或者绑定相应的函数,此时当订阅者Watcher接收到相应属性的变化,就会执行对应的更新函数,从而更新视图。因此接下去我们执行以下3个步骤,实现数据的双向绑定:

    1.实现一个监听器Observer,用来劫持并监听所有属性,如果有变动的,就通知订阅者。
    2.实现一个订阅者Watcher,可以收到属性的变化通知并执行相应的函数,从而更新视图。
    3.实现一个解析器Compile,可以扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相应的订阅器。

  7. vue-router的两种模式主要依赖什么实现?

    • hash主要依赖location.hash来改动url,达到不刷新跳转的效果,每次hash改变都会触发hashchange事件
    • history主要利用了h5的historyAPI来实现,用pushStatereplaceState来操作浏览历史记录
  8. Vue-router有哪几种导航守卫?

    • 全局守卫beforeEach beforeResolve、afterEach
    • 路由独享守卫 beforeEnter
    • 路由组件内守卫 beforeRouteEnter 、 beforeRouteUpdate、 beforeRouteLeave
  9. Vue-router的动态路由如何定义?怎样获取传过来的动态参数

    在router目录下的index.js文件中,对path属性加上/:id

    使用router对象的params.id

  10. scss是什么?在vue-cli中安装步骤?有哪些特性

    css的预编译

    1.用npm下三个loader(sass-loader、css-loader、node-sass)

    2.在build目录找到webpack.base.config.js,在extends属性中加一个扩展.scss

    3.在同一个文件,配置一个module属性

    4.在组件的style标签加上lang属性, 例如 lang=‘scss’

    特性:可以用变量、可以嵌套、可以用混合器

  11. 说说你对SPA单页面的理解,优缺点

    SPA( single-page application )仅在 Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS。一旦页面加载完成,SPA 不会因为用户的操作而进行页面的重新加载或跳转;取而代之的是利用路由机制实现 HTML 内容的变换,UI 与用户的交互,避免页面的重新加载。

    优点:

    • 用户体验好、快,内容的改变不需要重新加载整个页面,避免不必要的跳转和重复渲染
    • SPA相对服务器压力小
    • 前后端分离、架构清晰,前端进行交互逻辑,后端负责数据处理

    缺点:

    • 初次加载耗时多
    • 前进后退路由管理,由于单页应用在一个页面中显示所有内容,所以不能使用浏览器的前进后退功能,所有的页面切换需要自己建立堆栈管理
    • seo难度大
  12. Class与style如何动态绑定

    可以将属性值抽象出来赋予变量,通过v-bind绑定标签

  13. 怎样理解Vue的单向数据流

    所有的prop都使得其父子prop之间形成了一个单向下行绑定:父级prop的更新会向下流动到子组件中, 但反过来却不行

    这样会防止从子组件意外改变父级组件的状态,从而导致你的应用数据流向难以理解

    子组件想修改时,只能通过$emit派发一个自定义事件,父组件接收到后,由父组件修改

  14. computed和watch的区别和应用场景

    computed: 计算属性, 依赖其他属性值,并且computed的值有缓存,只有它依赖的属性值发生改变时,下一次获取computed的值才会重新计算

    watch: 更多的是观察作用,类似于某些数据的监听回调,每当监听的数据发生变化时都会执行回调后续操作

    场景:

    • 当我们需要进行数值计算,并依赖其他数据时,应当使用computed
    • 当我们需要在数据变化时执行异步或开销较大操作时,应该使用watch
  15. 直接给一个数组项赋值,Vue能检测到变化吗

    由于js的限制,Vue不能检测到以下数组变动

    • 利用索引设置一个数组项
    • 修改数组长度

    Vue提供了以下操作方法

    // Vue.set
    Vue.set(vm.items, indexOfItem, newValue)
    // Vue.$set
    Vue.$set(vm.items, indexOfItem, newValue)
    // Array.prototype.splice
    vm.items.splice(indexOfItem, 1, newValue)
    

    为了解决第二个问题,Vue提供了以下操作方法

    vm.items.splice(newLength)
    
  16. Vue父子组件生命周期钩子函数执行顺序

    加载渲染过程

    父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created -> 子 beforeMount -> 子 mounted -> 父 mounted

    子组件更新过程:

    父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated

    父组件更新过程:

    父 beforeUpdate -> 父 updated

    销毁过程:

    父 beforeDestroy -> 子 beforeDestroy -> 子 destroyed -> 父 destroyed

  17. 在哪个生命周期内调用异步请求

    可以在钩子函数created、beforeMount、mounted中进行调用,因为在这三个钩子函数中,data已经被创建,可以将服务端返回的数据进行赋值,但是更推荐在created钩子函数中调用异步请求,因为在created钩子函数中调用异步请求有以下优点:

    • 能更快获取到服务端数据,减少页面loading时间
    • ssr不支持beforeMount、mounted钩子函数,保证一致性
  18. 什么阶段可以访问操作DOM

    mounted

  19. 父组件可以监听到子组件的生命周期吗

    可以使用$emit触发父组件的事件,也可以在父组件引用子组件时通过@hook来监听

  20. 谈谈你对keep-alive的理解

    keep-alive是vue内置的一个组件,可以使被包含的组件保留状态,避免重新渲染

    有以下特性:

    • 一般会结合路由与动态组件一起使用,用于缓存组件
    • 提供include和exclude属性。两者都支持字符串和或正则表达式,include表示只有名称匹配的组件会被缓存
    • 对应两个钩子函数 activated 和 deactivated ,当组件被激活时,触发钩子函数 activated,当组件被移除时,触发钩子函数 deactivated
  21. 组件中data为什么是一个函数

    因为组件是用来复用的,且js中对象是引用关系,如果组件中data是一个对象,那么这样作用域没有隔离,子组件中的data属性值会相互影响

    而new Vue的实例,是不会被复用的,因此不存在引用对象的问题

  22. v-model的原理

    我们在 vue 项目中主要使用 v-model 指令在表单 input、textarea、select 等元素上创建双向数据绑定,我们知道 v-model 本质上不过是语法糖,v-model 在内部为不同的输入元素使用不同的属性并抛出不同的事件:

    • text 和 textarea 元素使用 value 属性和 input 事件;
    • checkbox 和 radio 使用 checked 属性和 change 事件;
    • select 字段将 value 作为 prop 并将 change 作为事件。

    以 input 表单元素为例:

    <input v-model='something'>
    
    相当于
    
    <input v-bind:value="something" v-on:input="something = $event.target.value">
    

    如果在自定义组件中,v-model 默认会利用名为 value 的 prop 和名为 input 的事件,如下所示:

    父组件:
    <ModelChild v-model="message"></ModelChild>
    
    子组件:
    <div>{{value}}</div>
    
    props:{
        value: String
    },
    methods: {
      test1(){
         this.$emit('input', '小红')
      },
    },
    
  23. 说说Vue SSR

    SSR大致的意思就是vue在客户端将标签渲染成的整个 html 片段的工作在服务端完成,服务端形成的html 片段直接返回给客户端这个过程就叫做服务端渲染。

    优点:

    • 更好的SEO
    • 更快的内容到达时间(首屏加载)

    缺点:

    • 开发条件限制,例如服务端渲染只支持beforeCreate和created两个钩子函数,会导致一些外部扩展库需要特殊处理,才能在服务端渲染应用程序中运行
    • 更多的服务器负载
  24. Vue怎么实现对象和数组的监听

    Vue 框架是通过遍历数组 和递归遍历对象,从而达到利用 Object.defineProperty() 也能对对象和数组(部分方法的操作)进行监听。

  25. Proxy与Object.defineProperty对比

    Proxy 的优势如下:

    • Proxy 可以直接监听对象而非属性;
    • Proxy 可以直接监听数组的变化;
    • Proxy 有多达 13 种拦截方法,不限于 apply、ownKeys、deleteProperty、has 等等是 Object.defineProperty 不具备的;
    • Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的,而 Object.defineProperty 只能遍历对象属性直接修改;
    • Proxy 作为新标准将受到浏览器厂商重点持续的性能优化,也就是传说中的新标准的性能红利;

    Object.defineProperty 的优势如下:

    • 兼容性好,支持 IE9,而 Proxy 的存在浏览器兼容性问题,而且无法用 polyfill 磨平,因此 Vue 的作者才声明需要等到下个大版本( 3.0 )才能用 Proxy 重写。
  26. Vue 怎么用 vm.$set() 解决对象新增属性不能响应的问题 ?

    vm.$set 的实现原理是:

    • 如果目标是数组,直接使用数组的 splice 方法触发相应式;
    • 如果目标是对象,会先判读属性是否存在、对象是否是响应式,最终如果要对属性进行响应式处理,则是通过调用 defineReactive 方法进行响应式处理( defineReactive 方法就是 Vue 在初始化对象时,给对象属性采用 Object.defineProperty 动态添加 getter 和 setter 的功能所调用的方法)
  27. 虚拟DOM优缺点

    优点:

    • 保证性能下限
    • 无需手动操作DOM
    • 跨平台

    缺点:

    • 无法进行极致优化,在一些性能要求极高的应用中虚拟DOM无法进行针对性的极致优化
  28. 虚拟Dom实现原理

    虚拟 DOM 的实现原理主要包括以下 3 部分:

    • 用 JavaScript 对象模拟真实 DOM 树,对真实 DOM 进行抽象;
    • diff 算法 — 比较两棵虚拟 DOM 树的差异;
    • pach 算法 — 将两个虚拟 DOM 对象的差异应用到真正的 DOM 树。
  29. Vue中的key的作用

    key 是为 Vue 中 vnode 的唯一标记,通过这个 key,我们的 diff 操作可以更准确、更快速。

    更准确:因为带 key 就不是就地复用了,在 sameNode 函数 a.key === b.key 对比中可以避免就地复用的情况。所以会更加准确。

    更快速:利用 key 的唯一性生成 map 对象来获取对应节点,比遍历方式更快

  30. 对Vue项目进行的优化

    代码层面的优化

    • v-if 和 v-show 区分使用场景
    • computed 和 watch 区分使用场景
    • v-for 遍历必须为 item 添加 key,且避免同时使用 v-if
    • 长列表性能优化
    • 事件的销毁
    • 图片资源懒加载
    • 路由懒加载
    • 第三方插件的按需引入
    • 优化无限列表性能
    • 服务端渲染 SSR or 预渲染

    webpack层面优化

    • Webpack 对图片进行压缩
    • 减少 ES6 转为 ES5 的冗余代码
    • 提取公共代码
    • 模板预编译
    • 提取组件的 CSS
    • 优化 SourceMap
    • 构建结果输出分析
    • Vue 项目的编译优化

    基础web技术优化

    • 开启 gzip 压缩
    • 浏览器缓存
    • CDN 的使用
    • 使用 Chrome Performance 查找性能瓶颈

三.架构

1.amd/cmd/commonjs差异

目前流行js的模块化规范有amd、cmd、commonjs
  • cmd和sea.js: cmd推崇依赖就近,延迟执行, 在需要时声明
  • amd和require.js: amd推崇依赖前置,提前执行,先声明后使用
  • commonJS用同步的方式加载模块
  • es6 module模块功能由两个命令exportimport构成

2.commonJS与ES6模块差异

  • CommonJS模块输出的是值的拷贝,一旦输出值,模块内部的变化不会影响到这个值。ES6机制是JS引擎静态分析脚本时,遇到import,会生成一个只读引用,当脚本执行时,再根据只读引用去模块中取值。因此ES6模块是动态引用,而且不会缓存值
  • CommonJS是运行时加载,即输入时先加载整个模块,然后生成一个对象,从这个对象中读取方法
  • ES6是编译时加载, 通过export命令显示指定输出的代码, import时可以指定加载某个输出值,而不是加载整个模块

3. Webpack? webpack常见优化手段

webpack是一个资源处理工具,可以对资源打包、解析、区分开发模式

常见优化:

  • 分离第三方依赖,比如引入dll
  • 引入多进程编译, 比如happypack
  • 提取公共的依赖模块
  • 资源混淆、压缩
  • 分离样式、减小bundle、chunk的大小
  • GZIP压缩

4. MVC、MVVM

MVC模式是软件分为三个部分: View\Controller\Model

  • 视图View: 用户界面
  • 控制器: 业务逻辑
  • 模型: 数据保存
1. view传送指令到Controller
2. Controller完成业务逻辑后,要求model改变状态
3. model将新的数据发送到view, 用户得到反馈
所有通信都是单向的

MVVM模式,采用双向绑定,view的变动,自动反映在viewmodel, 反之亦然
MVVM与MVC最大的区别就在于双向绑定

5.BFF架构

Backend For Frontend即后端服务于前端,为不同设备提供不同API

优点:

  • 能够满足因不同客户端特殊的交互引起的对新接口的要求,一开始就针对相应设备设计好对应的接口
  • 避免多端使用一个接口造成的耦合,或过多无用字段

缺点:

  • 代码重复、加大开发工作量

6.PWA

Progressive Web Apps 是 Google 提出的用前沿的 Web 技术为网页提供 App 般使用体验的一系列方案。

四. 网络

1.http请求资源过程

  • 查看浏览器中是否有缓存。有的话直接访问缓存
  • 如果缓存过期或没有,重新请求
  • 发送请求前,域名解析,获取相应ip地址
  • 浏览器与服务器发起tcp连接 三次握手
  • 握手成功,请求数据包
  • 服务器处理请求。返回数据给浏览器
  • 浏览器收到http响应
  • 读取页面内容,浏览器渲染,解析html源码

2.http状态码

  • 1xx, 信息、服务器收到请求。需要请求者继续执行操作
  • 2xx, 成功 操作被成功接收并处理
  • 3xx 重定向,需要进一步操作完成请求 304缓存 301,302重定向
  • 4xx 客户端错误
  • 5xx 服务端错误

3.http与https区别

  • http超文本传输协议,信息明文传输,安全性低,无状态连接,速度快
  • https比http多了个安全证书,采取的连接方式与http不同,由ssl+http协议构建的协议,可进行加密传输、身份认证

4.get与post区别

  • 请求参数长度不同,post没有长度限制
  • get明文拼接,post通过请求体发送参数、参数不会直接显示
发布了171 篇原创文章 · 获赞 246 · 访问量 24万+

猜你喜欢

转载自blog.csdn.net/weixin_42042680/article/details/100832537
今日推荐