前端面试相关

257 阅读12分钟

一、JS

数据类型


JS数据类型分为两大类:基本类型、对象类型

  1. 有哪些基本类型(7种)?

    • null
    • undeined
    • number
    • string
    • boolean
    • symbol
    • biginit
  2. 有哪些对象类型(2种)?

    • Object
    • Function

作用域和闭包


理解困难先看这里:彻底理解js作用域和闭包

  1. 全局对象是什么?

    浏览器环境下是window、node环境下是global(js引擎会把所有<script>标签整合到一起,生成一个GO对象)。

  2. 讲讲你对闭包的理解(概念和作用)?

    概念:当内部函数使用外部函数的变量,就会形成闭包。闭包是当前作用域的延伸。

    作用:在函数外部访问私有变量、实现封装、防止污染全局变量

  3. this的规则(要求能理解)

    一共有四种指向情况:

    • 默认绑定:指向全局对象(window);
    • 隐式绑定:函数被对象调用时,指向该对象;
    • 显式绑定:通过调用call()、apply()、bind()方法,使this指向新对象;
    • new绑定:通过构造函数调用,使this指向构造出的新对象。

    目的:区别这四种情况下的this指向。

    详细说明:www.cnblogs.com/xiaohuochai…

  4. 有哪些改变this指向的方法?

    apply、call和bind

  5. apply、call和bind的用法和区别?

    作用:方法重用,一个对象可以使用另一个对象的方法。

    区别(重要!):call多个参数用逗号分隔,apply多个参数使用数组接收、bind同call,但是返回的是函数。

    详细说明:

  6. 箭头函数和普通函数的区别?

    • 箭头函数里的this永远指向父级作用域;
    • 无法使用显式、隐式绑定改变this指向;
    • 不可以作为构造函数使用,即不能使用箭头函数实例化;
  7. 以下代码的执行结果(掌握以上内容即可理解答案)

     var name = 'window'
     var obj1 = {
         name: '1',
         fn1: function() {
           console.log(this.name)
         },
         fn2: () => console.log(this.name),
         fn3: function() {
           return function() {
             console.log(this.name)
           }
         },
         fn4: function() {
           return () => console.log(this.name)
         }
    }
    var obj2 = {
        name: '2'
    };
    obj1.fn1();
    obj1.fn1.call(obj2);
    
    obj1.fn2();
    obj1.fn2.call(obj2);
    
    obj1.fn3()();
    obj1.fn3().call(obj2);
    obj1.fn3.call(obj2)();
    
    obj1.fn4()();
    obj1.fn4().call(obj2);
    obj1.fn4.call(obj2)();
    
    // "1" 
    // "2" 
    // "window" 
    // "window"
    // "window" 
    // "2" 
    // "window" 
    // "1" 
    // "1" 
    // "2"
    

事件循环


理解困难先看这里:2分钟了解 JavaScript Event Loop事件循环(Event Loop)

  1. 简单描述一下事件循环?

    JavaScript是一种单线程的编程语言,为了解决单线程运行阻塞问题,JavaScript用到了计算机系统的一种运行机制,这种机制就叫做事件循环(Event Loop)

  2. 执行顺序

    • 先执行同步代码,
    • 遇到异步宏任务则将异步宏任务放入宏任务队列中,
    • 遇到异步微任务则将异步微任务放入微任务队列中,
    • 当所有同步代码执行完毕后,再将异步微任务从队列中调入主线程执行,
    • 微任务执行完毕后再将异步宏任务从队列中调入主线程执行,
    • 一直循环直至所有任务执行完毕。
  3. 有哪些你知道的宏任务?

    • setInterval()
    • setTimeout()
    • script
    • setImmediate
    • I/O
    • UI rendering
  4. 有哪些你知道的微任务?

    • Promise.then()
    • new MutaionObserver()
    • MutationObserver
  5. 以下代码的执行结果

    console.log('1');
    setTimeout(function() {
        console.log('2');
        new Promise(function(resolve) {
            console.log('3');
            resolve();
        }).then(function() {
            console.log('4');
        })
    })
    new Promise(function(resolve) {
        console.log('5');
        resolve();
    }).then(function() {
        console.log('6');
    })
    setTimeout(function() {
        console.log('7');
    })
    setTimeout(function() {
        console.log('8');
        new Promise(function(resolve) {
            console.log('9');
            resolve();
        }).then(function() {
            console.log('10');
        })
    })
    new Promise(function(resolve) {
        console.log('11');
        resolve();
    }).then(function() {
        console.log('12');
    })
    console.log('13');
    
    // "1" 
    // "5" 
    // "11" 
    // "13" 
    // "6" 
    // "12" 
    // "2" 
    // "3" 
    // "4" 
    // "7" 
    // "8" 
    // "9" 
    // "10"
    

类、对象和原型


  1. 描述一下原型链

    juejin.cn/post/684490…

    其实就是描述实例构造函数原型之间的关系

  2. 手写任意一种原型继承

    // 寄生组合式继承:
    
    function Parent() {} // 父类
    function Child() { // 子类
      Parent.call(this) // 继承实例上的属性
    }
    Child.prototype = Object.create(Parent.prototype, {
      constructor: { value: Child }
    })
    
  3. 你知道哪些判断数据类型的方式?

    • Object.prototype.toString.call()(最优)
    • instanceof(无法判断原始数据)
    • typeOf(无法判断null、array等Object类型)
  4. instanceof的原理和缺点?

    从原型链上判断一个值是否是一个原型的实例

    缺点:无法判断原始数据、所有对象的instanceof Object都是true

其他


  1. 简述并实现节流和防抖

    防抖

    说明:一段时间内,函数被触发多次,但是只执行一次并执行最新的(将多次执行变为最后一次执行)

    实现:每次触发重新开始计时。

    function debounce(fn) {
          let timeout = null; // 创建一个标记用来存放定时器的返回值
          return function () {
            clearTimeout(timeout); // 每当用户输入的时候把前一个 setTimeout clear 掉
            timeout = setTimeout(() => { // 然后又创建一个新的 setTimeout, 这样就能保证输入字符后的 interval 间隔内如果还有字符输入的话,就不会执行 fn 函数
              fn.apply(this, arguments);
            }, 500);
          };
        }
    function sayHi() {
      console.log('防抖成功');
    }
    
    var inp = document.getElementById('inp');
    inp.addEventListener('input', debounce(sayHi)); // 防抖
    

    节流

    说明:当持续触发某个事件时,会有规律的每隔一段时间就执行一次函数(将多次执行变成每隔一段时间执行)

    实现:每次触发,设置一个开关标记,第一次触发将开关关闭,并延时执行目标函数,目标函数执行完后再次打开开关。

    function throttle(fn) {
          let canRun = true; // 通过闭包保存一个标记
          return function () {
            if (!canRun) return; // 在函数开头判断标记是否为true,不为true则return
            canRun = false; // 立即设置为false
            setTimeout(() => { // 将外部传入的函数的执行放在setTimeout中
              fn.apply(this, arguments);
              // 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。当定时器没有执行的时候标记永远是false,在开头被return掉
              canRun = true;
            }, 500);
          };
        }
    function sayHi(e) {
      console.log(e.target.innerWidth, e.target.innerHeight);
    }
    window.addEventListener('resize', throttle(sayHi));
    
  2. 列举深拷贝和浅拷贝的方法

    浅拷贝:Object.assign、扩展运算符( b = {...a}

    深拷贝:JSON.parsInt(JSON.stringify(obj)、递归

  3. 数组去重有哪些方法?

    • ...new Set(arr)
    • arr.filter((item, index) => arr.Indexof(item, 0) === index)
    • 先排序再比较相邻元素
  4. 数组有哪些遍历方法,区别是什么?

  5. 简单的实现一个promise

ES6


  1. es6你知道的有哪些?

    www.runoob.com/w3cnote/es6…

  2. var、let和const的区别

    var:可以重复定义,可以修改;

    let:

    • 不可以重复定义;
    • 可以修改;
    • 块级作用域
    • 不影响作用域链

    const:

    • 不可以重复定义;
    • 不可以修改;
    • 块级作用域;
    • 一定要赋初始值;
    • 常量的值不能修改;
  3. CommenJs的模块化导入导出是怎样的?

    导出:module.exports={}

    导入:var xxx=require('/xxx.js')

  4. es6模块导入导出是怎样的?

    使用export导出

    使用import导入

二、HTML、CSS


  1. 列举实现水平居中的方法

    /* 1. margin: 0 auto */
    .class {
      width: 100px;
      margin: 0 auto
    }
    
    /* 2. text-align: center */
    .father-class {
      text-align: center;
       .son-class {
         display: inline-blick; // 行内元素
       }
    }
    
    /* 3. float&position */
    .page-div {
      float: left;
      width: 100%;
      overflow: hidden;
      position: relative;
      ul {
        clear: left;
        float: left;
        position: relative;
        left: 50%; /*整个分页向右移动宽度的50%*/
        text-align: center;
        li {
          line-height: 25px;
          margin: 0 5px;
          display: block;
          float: left;
          position: relative;
          right: 50%; /*将整个分页项向左边移动宽度的50%*/
        }
      }
    }
    
    /* 4. positon: absolute */
    .class {
      positon: absolute;
      width: 200px;
      left: 50%;
      margin-left: -100px;
    }
    
    /* 5. display: flex */
    .class {
      display: flex;
      justify-content: center;
    }
    
    /* 6. width: fit-content */
    .pagination ul {
      width: -moz-fit-content;
      width:-webkit-fit-content;
      width: fit-content;
      margin-left: auto;
      margin-right: auto;
    }
    .pagination li {
      line-height: 25px;
      margin: 0 5px;
      float: left;
    }
    
    
  2. 列举实现垂直居中的方法

    www.cnblogs.com/hutuzhu/p/4…

  3. html5有哪些新特性

    1. 语义化标签
    2. 增强型表单
    3. 新增视频 <video> 和音频 <audio> 标签
    4. Canvas绘图
    5. SVG绘图
    6. 地理定位
    7. 拖放API
    8. Web Worker
    9. Web Storage
    10. WebSocket
  4. css3有哪些新特性

    blog.csdn.net/chandoudeyu…

  5. 简述盒模型

    www.runoob.com/css/css-box…

  6. css权重规则

    www.cnblogs.com/dq-Leung/p/…

三、HTTP和浏览器


  1. http是什么?

    zhuanlan.zhihu.com/p/72616216

    超文本传输协议(HTTP,HyperText Transfer Protocol)

  2. http和https的区别

    • https是http的安全版本
    • 端口不同:http是80,https是443。
  3. http状态码有哪些,代表什么意思

    www.cnblogs.com/xiaomage666…

    说出代表性的几个:200、401、403、404、500

  4. 什么是跨域?

    域名、协议、端口号不同

  5. 怎么解决跨域?

    • 使用script标签
    • 使用jsonp(原理是动态创建scrip标签)
  6. cookie、seesionStorage、localStorage的区别

    特性CookieLocalStoragesessionStorage
    声明周期一般由服务器产生,可设置生效时间,如果在浏览器生产,默认事关闭浏览器后失效除非被清除,否则永久保存仅在当前会话有效,关闭浏览器或页面后被清除
    存放数据大小最大4kB一般5M同LocalStorage
    与服务器通信每次都会携带在HTTP中,如果使用cookie保存过多数据会带来性能问题仅在客户端中保存,不参与服务器通信同LocalStorage
    用途一般由服务器端生成,用于标识用户身份用于浏览器端缓存数据同LocalStorage
  7. 简述浏览器从输入url到渲染页面的过程

    1. DNS解析(将域名转换成ip地址(从DNS服务器和本地host文件获取解析))。
    2. TCP三次握手(三个报文)建立连接。
    3. 发送请求,分析url,设置请求报文。
    4. 服务器返回请求的文件(html)。
    5. 浏览器渲染:
      1. 构建dom树
      2. 生成style树
      3. dom树+style树 = 渲染树
      4. layout布局
      5. GPU painting 像素绘制页面
  8. 什么是回流、重绘

    回流一定会引起重绘,重绘不一定引起回流

    回流:当渲染树中的元素结构或尺寸等发生改变,浏览器重新渲染部分或全部文档的过程。

    • 页面首页渲染
    • 浏览器窗口大小发生变化
    • 内容变化
    • 添加或者删除节点
    • 激活CSS伪类
    • clinentWidth

    重绘:当页面中元素样式的改变不影响它在文档流中的位置,浏览器会将新样式赋予给元素的过程。

    • background
    • visibility

    性能:回流的性能消耗大于重绘性能

    优化-CSS:

    • 避免使用table布局
    • 避免设置多层内联样式
    • 使用transform代替top,left,margin等位移属性
    • 使用opacity代替visible

    优化-Javascript:

    • 避免频繁操作DOM
    • 对于大量插入DOM的操作,建议使用文档片段,也就是documentFragment

四、Vue


  1. 简述MVVM

    Model-View-ViewModel 使用ViewModel将Model和View关联起来、即使用ViewModel将数据和视图层分离,数据绑定到ViewModel再渲染到页面,视图变化后再由ViewModel更新数据。

  2. 简述spa

    概念:single-page-application 因为所有的页面都是挂载在id为app的根节点下,每次用户进行页面跳转都是利用路由在app下重新挂载、销毁。不用刷新整个页面。

    优点:不需要加载重载整个页面、服务压力小、前端架构清晰。

    缺点:初次加载耗时多、seo难度大、不能使用浏览器的前进后退功能。

  3. 简述vue的双向绑定原理

    数据改变视图、视图改变后再通过监听事件改变数据,利用Object.defineProperty()对数据进行劫持。

  4. 伴随v-for使用的key有什么作用?

    相当于身份id,相比没有key能更准确、更快的更新虚拟DOM,更好的让DOM-Diff识别。

    作用:准确(没有复用组件)、更快(利用key生成map对象,比遍历更快)

    • 使用index:key相同还是会复用组件,
    • 不加key默认使用index就地复用;
    • 同一组件内,key相同的情况下,标签也相同的话会产生复用;
  5. 为什么组件中只能有一个根元素?

    1. vue只能指定一个spa入口;
    2. 虚拟dom是树形结构,多个元素无法生成树形;
  6. 简述虚拟DOM和作用

    Virtual-DOM:模拟真实DOM的机构,通过数据追踪和**状态对比(DOM-Diff)**来减少对真实DOM的操作,提高效率。

    作用:浏览器直接操作dom很浪费性能,可以把dom元素标示成一个树形对象,再把树形对象渲染成真实dom

    1. 先实现虚拟dom:用一个对象来描述dom节点(使用jsx语法、render函数);
    2. 将虚拟节点转化成真是的dom节点,最后插入到app元素中;
  7. 组件中的data为什么是一个函数?

    组件被复用时,会创建多个实例,如果是对象,那么这些实例则共享一个对象,为了保证独立性使用函数返回一个对象。

  8. 有哪些生命周期函数

    • beforeCreate:组件实例被创建前,el,data,data中的message都为undefined
    • created:组件实例创建完成,el还是undefined
    • beforeMount:dom挂载之前
    • mounted:dom挂载完成
    • beforeUpdate:组件数据更新之前调用
    • update
    • activited、deactivated、beforeDestory、destoryed
  9. ajax请求放在哪个生命周期中?

    • 可以放在created、beforMounte和mounted中,生命周期是同步,ajax是异步。
    • 服务端渲染不支持mounted方法
  10. 何时使用beforeDestroy

    • 使用$on方法,需要在组件销毁前解绑;
    • 清除定时器
    • 解绑原生的dom操作scroll事件、mousemove事件...
  11. 有哪些你熟悉的指令

    常用:v-if、v-show、v-for、v-bind、v-on、v-model

  12. v-if和v-show的区别

    v-if:判断是否渲染节点,在编译阶段做处理;

    v-show:控制dom的visible,在编译render函数阶段,编译成指令;

  13. 为什么v-for和v-if不能连用

    v-for会比v-if的优先级更高,连用的话会把v-if给每个元素都添加,造成性能问题

  14. v-model的原理和自定义

    原理:在元素上创建双向绑定,绑定不同的属性,再通过不同的事件来改变值

  15. 组件通信有哪些方法?

    • props
    • vuex
    • sessionStorage
    • ref
    • bus
  16. computed和watch的作用和特性

五、项目/应用


  1. 你对项目做过哪些优化?

    • 基础优化

      1. 开启Gzip压缩

      2. 图片使用链接(上传到CDN)

      3. 图片压缩

      4. 第三方插件按需引入

      5. 路由懒加载

      6. 图片资源预加载(使用Preload.js)

      7. 图片资源懒加载(可视区域不加载,使用vue-lazyload)

      8. 使用keep-alive缓存路由:

        在路由路由对象的mata对象中加入keepAlive属性;

        每次路由刷新都往vuex里存放路由name

        不需要缓存时,清除vuex里存放的name

    • 其他优化

      1. 模块化:
  2. 你的项目有哪些亮点/难点?

七、人事


  1. 你有什么优点/缺点?

  2. 近3/5年有什么规划?

  3. 你觉得你有哪些优势?

  4. 为什么从上一家公司离职?

  5. 你有什么想要问我的?

    技术:

     公司使用什么技术栈?
     公司技术部(前端)人员构成?
    

    福利:

     福利、年终奖
     公积金
     加班、加班补贴
     上班时间