前端面试自测题【vue、react、css、html、js】

2,452 阅读18分钟

前端面试题

前言

观看方式: 根据问题, 先自己思索答案, 有了答案之后再看答案, 把查看的答案与自己的答案做对比, 最终组织成自己的语言

HTML篇

1.H5的新特性有哪些?

下拉查看
  • 画布(Canvas) API
  • 地理(Geolocation) AP
  • 音频、视频APl(audio,video)
  • localStorage和sessionStorager
  • webworker, websockete www
  • 2.iframe有哪些缺点

    下拉查看
  • 1. iframe会阻塞主页面的 Onload 事件;
  • 2. 搜索引擎的检索程序无法解读这种页面,不利于SEO;
  • 3. iframe和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载。
  • 4. 使用iframe之前需要考虑这两个缺点。如果需要使用iframe,最好是通过javascript
  • 5. 动态给iframe添加src属性值,这样可以绕开以上两个问题。
  • 3.实现不使用 border 画出1px高的线

    下拉查看
  • 在不同浏览器的标准模式与怪异模式下都能保持一致的效果
  • div style="height:1px;overflow:hidden;background:red"
  • 4.如何实现浏览器内多个标签页之间的通信? (阿里)

    下拉查看
  • 1. WebSocket、SharedWorker;
  • 2. 也可以调用localstorge、cookies等本地存储方式;
  • localstorge另一个浏览上下文里被添加、修改或删除时,它都会触发一个事件, 我们通过监听事件,控制它的值来进行页面信息通信; 注意quirks:Safari 在无痕模式下设置localstorge值时会抛出 QuotaExceededError 的异常
  • 5.两种实现前端路由的方式

    下拉查看
  • HTML5 History两个新增的API:history.pushState 和 history.replaceState,两个 API 都会操作浏览器的历史记录,而不会引起页面的刷新。
  • Hash就是url 中看到 # ,我们需要一个根据监听哈希变化触发的事件( hashchange) 事件。我们用 window.location 处理哈希的改变时不会重新渲染页面,而是当作新页面加到历史记录中,这样我们跳转页面就可以在 hashchange 事件中注册 ajax 从而改变页面内容。 可以为hash的改变添加监听事件:
  • window.addEventListener("hashchange", furfuncRef, false)
  • 优点: 从性能和用户体验的层面来比较的话,后端路由每次访问一个新页面的时候都要向服务器发送请求,然后服务器再响应请求,这个过程肯定会有延迟。而前端路由在访问一个新页面的时候仅仅是变换了一下路径而已,没有了网络延迟,对于用户体验来说会有相当大的提升. 前端路由的优点有很多,比如页面持久性,像大部分音乐网站,你都可以在播放歌曲的同时,跳转到别的页面而音乐没有中断,再比如前后端彻底分离。 开发一个前端路由,主要考虑到页面的可插拔、页面的生命周期、内存管理等
  • 缺点: 使用浏览器的前进,后退键的时候会重新发送请求,没有合理地利用缓存。 History interface提供了两个新的方法:pushState(), replaceState()使得我们可以对浏览器历史记录栈进行修改: window.history.pushState(stateObject, title, URL) window.history.replaceState(stateObject, title, URL)
  • 6.浏览器渲染原理解析

    下拉查看
  • 1.首先渲染引擎下载HTML,解析生成DOM Tree
  • 2.遇到 css 标签或 JS 脚本标签就新起线程去下载他们,并继续构建DOM。(其中css是异步下载同步执行)浏览器引擎通过 DOM Tree 和 CSS Rule Tree 构建 Rendering Tree
  • 3.通过 CSS Rule Tree 匹配 DOM Tree 进行定位坐标和大小,这个过程称为 Flow 或 Layout
  • 4.最终通过调用Native GUI 的 API 绘制网页画面的过程称为 Paint
    当用户在浏览网页时进行交互或通过 js 脚本改变页面结构时,以上的部分操作有可能重复运行,此过程称为 Repaint 或 Reflow。 重排是指dom树发生结构变化后,需要重新构建dom结构。 重绘是指dom节点样式改变,重新绘制。 重排一定会带来重绘,重绘不一定有重排。
    如何减少浏览器重排:将需要多次重排的元素,position属性设为absolute或fixed,这样此元素就脱离了文档流,它的变化不会影响到其他元素
  • CSS篇

    1.CSS隐藏元素的几种方法(至少说出三种)

    下拉查看
    答案:
        opacity: 元素依然占有位置,对网页依然起布局作用
        visibility: 与opacity唯一不同的是它不会响应任何用户交互
        display:display 设为 none 任何对该元素直接打用户交互操作都不可能生效
      

    2.px和em的区别

    下拉查看
    答案:
        px 和 em 都是长度单位,区别是,px 的值是固定的,指定是多少就是多少,计算比较容易。em 得值不是固定的,并且 em 会继承父级元素的字体大小。
        浏览器的默认字体高都是 16px。所以未经调整的浏览器都符合: 1em=16px。那么 12px=0.75em, 10px=0.625em。
      

    3.什么是BFC?

    下拉查看
    1.什么是 BFC:
        BFC(Block Formatting Context)格式化上下文,是 Web 页面中盒模型布局的 CSS 渲染模式,指一个独立的渲染区域或者说是一个隔离的独立容器。
      2.形成 BFC 的条件:
        浮动元素,float 除 none 以外的值
        定位元素,position(absolute,fixed)
        display 为以下其中之一的值 inline-block,table-cell,table-caption
        overflow 除了 visible 以外的值(hidden,auto,scroll)
      3.BFC 的特性:
        BFC的块不会和浮动块重叠
        计算BFC元素的高度时,会包括浮动元素
        垂直方向上的距离由 margin 决定
        BFC元素是一个独立的容器,使得里面的元素和外部元素隔离开,互补影响
      

    4.Sass, LESS是什么?大家为什么要使用他们?

    下拉查看
    答案:他们是 CSS 预处理器。他是 CSS 上的一种抽象层。他们是一种特殊的语法/语言编译成 CSS。
        例如 Less 是一种动态样式语言. 将 CSS 赋予了动态语言的特性,如变量,继承,运算, 函数. LESS 既可以在客户端上运行 (支持 IE 6+, Webkit, Firefox),也可一在服务端运行 (借助 Node.js)。
      为什么要使用它们?
        结构清晰,便于扩展。
        完全兼容 CSS 代码,可以方便地应用到老项目中。LESS 只是在 CSS 语法上做了扩展,所以老的 CSS 代码也可以与 LESS 代码一同编译。
      

    5.移动端1px问题的解决办法

    下拉查看
    答案:边框使用伪类选择器,或者单独的元素实现。例如底部边框
      答案:边框使用伪类选择器,或者单独的元素实现。例如底部边框
      
      .box2::after{
          content:'';
          height:1px;
          width:100%;
          position:absolute;
          left:0;
          bottom:0;
          background:#000;
      }
      /* 在高清屏下设置 */
      @media screen and (-webkit-min-device-pixel-ratio: 2){
          .box2{
              /* 左右是水平x,上下是出垂直y */
              transform:scaleY(0.5);
          }
      }
      @media screen and (-webkit-min-device-pixel-ratio: 3){
          .box2{
              transform:scaleY(0.33333);
          }
      }
      
      
      

    JavaScript篇

    1.onload 和 DOMContentloaded 的区别

    下拉查看
    页面加载完成有两种事件
        1.load是页面当中所有资源全部加载完毕后(DOM树, css文件, js文件, 图片资源等)行一个函数问题:如果图片资源较多,加载时间较长,onload后等待执行的函数需要等待较	长时间,所以一些效果可能受到影响
        2.DOMContentloaded是当DOM文档树加载完成后执行一个函数 (不包含图片,css等)	  所以会比load较快执行
      

    2.null 和 undefined 的区别

    下拉查看
    1.首先 Undefined 和 Null 都是基本数据类型,这两个基本数据类型分别都只有一个值,就是 undefined 和 null。
      2.undefined 代表的含义是未定义,null 代表的含义是空对象。一般变量声明了但还没有定义的时候会返回 undefined,null主要用于赋值给一些可能会返回对象的变量,作为初始化。
      3.undefined 在 js 中不是一个保留字,这意味着我们可以使用 undefined 来作为一个变量名,这样的做法是非常危险的,它会影响我们对 undefined 值的判断。
      4.当我们对两种类型使用 typeof 进行判断的时候,Null 类型化会返回 “object”,这是一个历史遗留的问题。当我们使用双等号对两种类型的值进行比较时会返回 true,使用三个等号时会返回 false。
      

    3.JavaScript 中如何检测一个变量是一个 String 类型?

    下拉查看
     1.typeof
          typeof('123') === "string" // true
          typeof '123' === "string" // true
      2.constructor
         '123'.__proto__.constructor === String === String // true
      3.Object.prototype.toString.call()
         Object.prototype.toString.call('123') === '[object String]' // true
          
      
      

    4.js 是一门怎样的语言,它有什么特点

    下拉查看
      1.脚本语言。JavaScript 是一种解释型的脚本语言,C、C++等语言先编译后执行,而 JavaScript 是在程序的运行过程中逐行进行解释。
        2.基于对象。JavaScript 是一种基于对象的脚本语言,它不仅可以创建对象,也能使用现有的对象。
        3.简单。JavaScript 语言中采用的是弱类型的变量类型,对使用的数据类型未做出严格的要求,是基于 Java 基本语句和控制的脚本语言,其设计简单紧凑。
        4.动态性。JavaScript 是一种采用事件驱动的脚本语言,它不需要经过 Web 服务器就可以对用户的输入做出响应。
        5.跨平台性。JavaScript 脚本语言不依赖于操作系统,仅需要浏览器的支持。
      

    5.事件委托是什么

    下拉查看
    答案:利用事件冒泡的原理,让自己的所触发的事件,让他的父元素代替执行!
    1.那什么样的事件可以用事件委托,什么样的事件不可以用呢?
  • 适合用事件委托的事件:click,mousedown,mouseup,keydown,keyup,keypress。
  • 值得注意的是,mouseover 和 mouseout 虽然也有事件冒泡,但是处理它们的时候需要特别的注意,因为需要经常计算它们的位置,处理起来不太容易。
  • 不适合的就有很多了,举个例子,mousemove,每次都要计算它的位置,非常不好把控,在不如说 focus,blur 之类的,本身就没用冒泡的特性,自然就不用事件委托了。
  • 2.为什么要用事件委托: 提高性能,代码简洁

    6.什么是原型链?

    下拉查看
    答案:实例对象__proto__与原型对象之间的关系,通过一个对象的__proto__可以找到它的原型对象,原型对象也是一个对象,就可以通过原型对象的__proto__,最后找到了我们的 Object.prototype,从实例的原型对象开始一直到 Object.prototype 就是我们的原型链
      
      

    7. || 和 &&操作符的返回值?

    下拉查看
    1.|| 和 && 首先会对第一个操作数执行条件判断,如果其不是布尔值就先进行 ToBoolean 强制类型转换,然后再执行条件判断。
      2.对于 || 来说,如果条件判断结果为 true 就返回第一个操作数的值,如果为 false 就返回第二个操作数的值。
      3.&& 则相反,如果条件判断结果为 true 就返回第二个操作数的值,如果为 false 就返回第一个操作数的值。
      4.|| 和 && 返回它们其中一个操作数的值,而非条件判断的结果
      

    Vue篇

    1.什么是Vue生命周期?

    下拉查看
      Vue 实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是 Vue 的生命周期
    2.v-show与v-if区别
    下拉查看
  • v-show是css切换,v-if是完整的销毁和重新创建
  • 频繁切换时用v-show,运行时较少改变时用v-if
  • v-if= 'false' v-if是条件渲染,当false的时候不会渲染e
  • 3.MVVM相关

    下拉查看
    vue采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty劫持data属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
    MVVM
  • M - Model Model:代表数据模型,也可以在 Model 中定义数据修改和操作的业务逻辑
  • V - View View:代表 UI 组件,它负责将数据模型转化为 UI 展现出来
  • VM - ViewModel ViewModel:监听模型数据的改变和控制视图行为、处理用户交互,简单理解就是一个同步 View 和 Model 的对象,连接 Model 和 View
  • image.png

    4.说说你对SPA单页面的理解,它的优缺点分别是什么?

    下拉查看
       仅在 Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS。一旦页面加载完成,SPA 不会因为用户的操作而进行页面的重新加载或跳转;取而代之的是利用路由机制实现 HTML 内容的变换,UI 与用户的交互,避免页面的重新加载。
    优点:
  • 用户体验好、快,内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染;
  • 基于上面一点, SPA相对对服务器压力小
  • 前后端职责分离,架构清晰
  • 缺点:
  • 初次加载耗时多:为实现单页Web应用功能及显示效果,需要在加载页 面的时候将JavaScript, Css统一加载,部分页面按需加载;e
  • SEO上其有着天然的弱势。
  • 5.computed和watch的区别和运用的场景?
    下拉查看
  • computed: 是计算属性,依赖其它属性值,并且 computed 的值有缓存,只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值

  • watch: 更多的是「观察」的作用,类似于某些数据的监听回调 ,每当监听的数据变化时都会执行回调进行后续操作
  • 6.Vue和React的区别?

    下拉查看
  • React: react整体是函数式的思想,把组件设计成纯组件, 状态和逻辑通过参数传入, 所以在react中, 是单向数据流

  • Vue: vue的思想是响应式的, 也就是基于是数据可变的, 通过对每一个属性建立, Watcher来监听, 当属性变化的时候, 响应式的更新对应的虚拟dom
  • 7.为什么在Vue3.0采用了Proxy,抛弃Object.defineProperty?

    下拉查看
        Object.defineProperty 只能劫持对象的属性,因此我们需要对每个对象的每个属性进行遍历。Vue 2.x 里,是通过 递归 + 遍历 data 对象来实现对数据的监控的,如果属性值也是对象那么需要深度遍历,显然如果能劫持一个完整的对象是才是更好的选择
          Proxy 可以劫持整个对象,并返回一个新的对象。Proxy 不仅可以代理对象,还可以代理数组。还可以代理动态增加的属性。 

    8.Vue组件data为什么必须是函数?

    下拉查看
     因为组件是可以复用的, JS 里对象是引用关系,如果组件 data 是一个对象,那么子组件中的 data 属性值会互相污染,产生副作用。
    所以一个组件的 data 选项必须是一个函数, 因此每个实例可以维护一份被返回对象的独立的拷贝。new Vue 的实例是不会被复用的,因此不存在以上问题
    9.谈谈你对keep-alive的了解?
    下拉查看
     keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,避免重新渲染 
      一般结合路由和动态组件一起使用,用于缓存组件

    10.Vue组件间通信有哪几种方式?

    下拉查看
  • 1. props / $emit 适用 父子组件通信
  • 2. ref 与 $parent / $children 适用 父子组件通信
  • 3. EventBus ($emit/$on) 适用于 父子、隔代、兄弟组件通信
  • 4. $attrs/$listeners 适用于 隔代组件通信
  • 5. provide / inject 适用于 隔代组件通信
  • 6. Vuex 适用于 父子、隔代、兄弟组件通信
  • 11.请介绍一下你对vuex的理解?

    下拉查看
     Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。每一个 Vuex 应用的核心就是 store(仓库)。“store” 基本上就是一个容器,它包含着你的应用中大部分的状态 ( state )。
        (1)Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
        (2)改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化。
        主要包括以下几个模块:
      
  • State:定义了应用状态的数据结构,可以在这里设置默认的初始状态
  • Getter:允许组件从 Store 中获取数据,mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性
  • Mutation:是唯一更改 store 中状态的方法,且必须是同步函数
  • Action:用于提交 mutation,而不是直接变更状态,可以包含任意异步操作
  • Module:允许将单一的 Store 拆分为多个 store 且同时保存在单一的状态树中。
  • 12.Vue中的key有什么作用?

    下拉查看
    	 Vue 中 key 的作用是:key 是为 Vue 中 vnode 的唯一标记,通过这个 key,我们的 diff 操作可以更准确、更快速 
        更准确:因为带 key 就不是就地复用了,在 sameNode 函数 a.key === b.key 对比中可以避免就地复用的情况。所以会更加准确。
        更快速:利用 key 的唯一性生成 map 对象来获取对应节点,比遍历方式更快

    14.ref的作用

    下拉查看
  • 1. 获取dom元素this.$refs.box
  • 2. 获取子组件中的datathis.$refs.box.msg
  • 3. 调用子组件中的方法this.$refs.box.open()
  • React

    1.React中 key 的作用是什么?
    下拉查看
  • key 是用来帮助 react 识别哪些内容被更改、添加或者删除
  • key 需要写在用数组渲染出来的元素内部,并且需要赋予其一个唯一的值
  • 唯一在这里很重要,因为如果 key 值发生了变更,react 则会触发 UI 的重渲染
  • 2.调用setState之后发生了什么?

    下拉查看
    通知 react 组件数据有更新, 需要重新渲染
      它是异步的, react通常会集齐一批需要更新的组件, 然后一次性更新绑定渲染的性能

    3.什么是虚拟DOM?

    下拉查看
     虚拟DOM 相当于在JS和真实DOM中间加了一个缓存, 利用dom diff算法避免了没有必要的 dom 操作, 从而提高性能。
  • 1. 用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文档当中
  • 2. 当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异
  • 3. 把两所记录的差异应用到步骤一所构建的真正的DOM树上,视图就更新了
  • 4. 把树形结构按照层级分解,只比较同级元素。
  • 4.类组件和函数组件之间的区别是啥?
    下拉查看
      1.类组件可以使用其他特性,如状态state和生命周期钩子。
    2.当组件只是接收 props 渲染到页面时,就是无状态组件,就属于函数组件,也被称为哑组件或展示组件。
    3.函数组件和类组件当然是有区别的,而且函数组件的性能比类组件的性能要高,因为类组件使用的时候要实例化,而函数组件直接执行函数取返回结果即可。为了提高性能,尽量使用函数组件。

    5.rceact性能优化是哪个周期函数?

    下拉查看
     shouldComponentUpdate 这个方法用来判断是否需要调用render方法重新描绘dom。
      因为dom的描绘非常消耗性能,如果我们能在shouldComponentUpdate方法中能够写出更优化的dom diff算法,可以极大的提高性能。

    6.什么是高阶组件?

    下拉查看
      高阶组件(HOC)是接收一个组件并返回一个新组件的函数。 
      这是一个模式,是从 React 的组合特性中衍生出来的,称其为纯组件
      因为它们可以接受任何动态提供的子组件,但不会修改或复制输入组件中的任何行为。

    7.Hос可以干什么?

    下拉查看
  • 代码重用、逻辑
  • 渲染劫持
  • state抽象和操作
  • props处理
  • 8.什么是受控组件?

    下拉查看
    在包含表单的组件将跟踪其状态的输入值, 并在每次回调函数(例如onChange)触发时重新渲染组件,因为状态被更新。以这种方式由 React 控制其值的输入表单元素称为受控组件。

    9.受控组件和非受控组件区别是啥?

    下拉查看
  • 1. 受控组件是 React 控制中的组件,并且是表单数据真实的唯一来源。
  • 2. 非受控组件是由 DOM 处理表单数据的地方,而不是在 React 组件中。
  • 10.React的生命周期方法有哪些?

    下拉查看
    1. componentWillMount:在渲染之前执行,用于根组件中的 App 级配置。
    2. componentDidMount:在第一次渲染之后执行,可以在这里做AJAX请求,DOM 的操作或状态更新以及设置事件监听器。
    3. componentWillReceiveProps:在初始化render的时候不会执行,它会在组件接受到新的状态(Props)时被触发,一般用于父组件状态更新时子组件的重新渲染
    4. shouldComponentUpdate:确定是否更新组件。默认情况下,它返回true。如果确定在 state 或 props 更新后组件不需要在重新渲染,则可以返回false,这是一个提高性能的方法。
    5. componentWillUpdate:在shouldComponentUpdate返回 true 确定要更新组件之前件之前执行。
    6. componentDidUpdate:它主要用于更新DOM以响应props或state更改。
    7. componentWillUnmount:它用于取消任何的网络请求,或删除与组件关联的所有事件监听器

    11.使用React Hooks好处是啥?

    下拉查看
    首先,Hooks 通常支持提取和重用跨多个组件通用的有状态逻辑,而无需承担高阶组件或渲染 props 的负担。
    Hooks 可以轻松地操作函数组件的状态,而不需要将它们转换为类组件。

    12.了解redux么,说一下redux的作用和运用流程,redux有什么缺点

    下拉查看
    Redux 是一个 数据管理中心,可以把它理解为一个全局的 data store 实例。它通过一定的使用规则和限制,保证着数据的健壮性、可追溯和可预测性。
    它与 React 无关,可以独立运行于任何 JavaScript 环境中,从而也为同构应用提供了更好的数据同步通道。
    redux核心理念
  • 单一数据源: 整个应用只有唯一的状态树,也就是所有 state 最终维护在一个根级 Store 中;
  • 状态只读: 为了保证状态的可控性,最好的方式就是监控状态的变化。那这里就两个必要条件
    (1)Redux Store 中的数据无法被直接修改;
    (2)严格控制修改的执行;
  • 纯函数: 规定只能通过一个纯函数(Reducer)来描述修改;