首页 > 其他分享 >前端基础面试题

前端基础面试题

时间:2022-09-28 09:14:51浏览次数:89  
标签:function 面试题 name 前端 基础 原型 函数 父类 构造函数

1. 前端如何进行性能优化?

前端进行性能优化的方案很多,这里只列举部分。
在实际应用中不要贪多,想着都用上,要对网站的主要用户群体进行针对性优化。
  • 降低请求量
    • 合并资源,减少 http 请求数量。
    • lazyLoad,如图片懒加载。分批加载,每次只加载一部分。
    • 使用字体图标或 CSS 绘制,来代替部分图片。
  • 加快请求速度
    • 预解析 DNS
    • 使用 HTTP2.0
    • 并行加载
    • CDN 分发
    • webP,对图片进行压缩,减少图片体积。
    • minify/gzip 压缩,对 css、js 等文件进行压缩(去除空格、回车等),减少文件体积
    • 补充知识:
      • webP 的优势体现在它具有更优的图像数据压缩算法,能带来更小的图片体积,而且图像质量几乎无差异。同时具备了无损和有损的压缩模式、Alpha 透明以及动画的特性,在 JPEG 和 PNG 上的转化效果都相当优秀。
      • Minify 把 CSS 和 JS 压缩和削减(Minify:去掉空格回车符等),以及把多个 CSS,JS 文件整合到一个文件里。
  • 缓存
    • HTTP 协议缓存请求
    • 离线缓存 manifest
    • 本地缓存 localStorage
    • 补充知识:
      • GET 请求可以缓存,POST 请求不能缓存。GET 请求后退/刷新无害,POST 后退/刷新则会致使重新提交数据
  • 渲染
    • JS 优化,如防抖、节流、事件委托、减少重排重绘等。
    • CSS 优化,如提取公共样式减少代码量、减少选择器嵌套层数等。
    • 服务器端渲染
    • 使用 Web Workers
    • CSS 写在文件头部,JS 写在文件底部。
    • 补充知识:
      • 客户端渲染: 获取 HTML 文件,根据需要下载 JavaScript 文件,运行文件,生成 DOM,再渲染。
      • 服务端渲染:服务端返回 HTML 文件,客户端只需解析 HTML,使首屏渲染快,SEO(搜索引擎优化) 好。

2. 描述事件委托的原理并说说它的好处?

  • 事件冒泡 和 DOM 遍历
  • 好处
    • 可以大量节省内存占用,减少事件注册。(比如 ul 上代理所有 li 的 click 事件就很不错)
    • 可以实现当新增子对象时,无需再对其进行事件绑定 (对于动态内容部分尤为合适)
  • 缺点
    • 事件委托基于冒泡, 对于不冒泡的事件不支持
    • 如果把所有事件都用事件代理,可能会出现事件误判。(即本不该被触发的事件被绑定上了事件)

3. es5 实现继承的方式有哪些?

  • 原型链继承 (子类的原型等于父类的实例)

    • 缺点:
      • 子类无法向父类的构造函数传参. new Sub( name )父类也接收不到
      • 子类修改父类原型中引用类型的值时,原型的属性发生改变,导致之后的实例的值都发生改变
  • 借用构造函数继承 (通过 call 、apply 将父类构造函数的方法引入子类)

    • 优点
      • 解决了子类实例向父类传参的缺点
      • 解决了子类实例修改父类原型属性或者方法的问题
      • 可以继承多个构造函数属性(call 多个)
    • 缺点
      • 无法继承父类原型的方法和属性
      • 每个新实例都有父类构造函数的副本,无法复用,臃肿。
  • 组合继承 (j 原型链继承 + 构造函数继承 )

    • 优点
      • 可传参 + 继承了父类的原型
    • 缺点
      • 两次调用父类的构造函数(耗内存)
    // 父类
    function Super(name) {
      this.name = name;
    }
    Super.prototype = {
      name: "我要走走看看",
      age: 18,
      hobby: { a: "篮球" },
    };
    // 子类
    function Sub(name) {
      Super.call(this, name); // 1: 调用第一次
    }
    Sub.prototype = new Super(); // 2: 调用第二次
    
  • 原型式继承

    • 缺点
      • 无法复用,原型都是手动添加上去的
      function Super(name) {
        this.name = name
      }
      Super.prototype.sayName = function() {
          console.log(this.name)
      }
      const a = new Super('姓名')
    
      // 第一种
      function inherit(o) {
          function F() {}
          F.prototype = o
          return new F()
      }
      const b1 = inherit(a)
    
      // 第二种 普通用法
      // const b1 = Object.create(a)
    
      // Object.create 增加额外的属性
      const b1 = Object.create(a, {
        age: {
            value: 15,
            writable: true,
        },
        address: {
            value: '上海',
            writable: true,
        },
      })
    
      console.log(b.name) // 姓名
    
  • 寄生组合式继承(常用)

    • 优点
      • 既可以传参又实现了原型的复用
      function Super(name) {
        this.name = name
        this.age = 21
      }
      Super.prototype = Object.assign({
          sayName: () => {
              console.log(this.name)
          },
          address: '上海',
          hobby: ['唱歌'],
      })
    
      function Sub(name) {
          Super.call(this, name) // 继承父类构造函数的属性
      }
      Sub.prototype = Object.create(Super.prototype) // 继承父类的原型
      const sub1 = new Sub('姓名1')
      console.log(this.name) // 姓名1
    

4. 实现深浅拷贝的方式都有哪些?如何判断是深拷贝还是浅拷贝?

  • 方法
    • jQ对象上的extend方法

         var obj = {name:1, girl:{name: '花花'}}
          var newObj = {}
          // 在引入jq后
          // true为深拷贝;反之false为浅拷贝 => 目标对象 => 源对象
          $.extend(true, newObj, obj)
      
    • JSON对象的parse和stringift

    • 递归遍历

  • 判断
    • 改变拷贝后的新数据,如果源数据发生变化则是浅拷贝,反之则是深拷贝

5. js 如何检测数据的类型?这些方法都有什么局限性?

  • typeof
    • 只能检测除null的基本数据类型,检测引用数据类型除function以外,都是object
  • instanceof
    • 可以准确地判断复杂引用数据类型(原型链也会检测)
    • 基本数据类型检测补全(undefined、null、symbol)
  • constructor
    • 适合检测引用数据类型(不会检测原型链)
  • Object.prototype.toString.cal()
    • 适用于所有类型(除对象可以不改变this指向 => 可以不加.call)

6. 原型、构造函数、实例对象之间有什么关系?原型指的是什么?原型的作用有哪些?

  • 关系
    • 任何一个对象都有constructor属性,实例化对象的constructor属性指向构造函数
    • 原型也是对象,也有constructor属性,构造函数的原型的constructor属性指向构造函数
    • 实例对象的__proto__指向于它构造函数的原型
  • 原型是什么
    • 任何一个函数都有prototype属性,它本身是一个对象,称之为原型、
  • 原型作用
    • 存放所有实例对象需要数据共享(属性或方法),
    • 节省了内存空间,
    • 避免了全局污染

7. 描述 Vue 响应式是怎么实现的?

  • vue.js是采用数据劫持与发布者、订阅者的模式的方式,通过Object.defineProperty()来劫持各个属性的getter、setter,在数据变动时发布消息给订阅者,触发相应的监听回调来渲染视图

8. 不建议用 index 做 key 的原因是什么?key 的作用有哪些?

  • 原因
    • 用 index 作为 key 时,在对数据进行,逆序添加,逆序删除等破坏顺序的操作时,会产生没必要的真实 DOM更新,从而导致效率低
  • 作用
    • key 是虚拟 DOM 对象的唯一标识
    • 在 diff 算法中 key 起着极其重要的作用。

9. 如何解决 vue 为 data 中的对象 新增属性无法更新视图?无法更新视图的原因是什么?

  • 解决
    • 对象添加少量的新属性,可以直接采用Vue.set()
    • 对象添加大量的新属性,则通过Object.assign()创建新对象
    • 强制刷新时,可采取$forceUpdate() (不建议)
    • nextTick()
  • 原因
    • 组件初始化时,对data中的obj进行递归遍历,对obj的每一个属性进行劫持,添加set,get方法,新增对象属性没有通过Obgect.defineProperty设置为响应式,所以不会渲染视图

10. vue 路由里的$router和$route 的区别是什么?

  • $router
    • $router是全局 router 的实例, 包含了一些路由的跳转方法 push, replace等
  • $route
    • $route是当前激活路由的信息对象。每个对象都是局部的,可以获取当前路由的 path, name, params, query 等属性

11. watch 和 computed 的区别?

  • watch没有缓存, computed有缓存
  • watch可以监听异步, computed无法监听异步数据变化
  • watch监听的数据发生变化时,立即触发回调函数; computed只有依赖的数据变化时才会重新调用getter

12. 手写一个函数防抖,并分别解释防抖和节流。

  • 防抖是指在事件被触发 n 秒后再执行回调,如果在这 n 秒内事件又被触发,则重新计时。

  • 节流是指规定一个单位时间内,只能有第一次触发事件的回调函数执行

    // 防抖
      function fangdou(fn,time){
        let timer=null;
        return function(){
          let context=this;
          let args=arguments;
          //如果此时定时器已经存在了,则取消之前的定时器重新计时
          if(!timer){
            clearTimeout(timer);
            timer=null;
          }
          //设置定时器,使事件间隔指定事件后触发
          timer=setTimeout(()=>{
            fn.apply(context,args);
          },time);
        };
      }
    
    // 节流
      function jieliu(fn,time){
        let timer=null;
        return function(){
          let context=this;
          let args=arguments;
          if(!timer){
            timer=setTimeout(()=>{
              fn.apply(context,args);
              timer=null;
            },time);
          }
        }
      }
    

13. 箭头函数与普通函数的区别?

  • 外形不同:箭头函数使用箭头定义,普通函数中没有。
  • 命名不同:箭头函数全是匿名函数,普通函数可以有匿名函数,也可以有具名函数
  • 用于构造函数:箭头函数不可用于构造函数,普通函数可以用于构造函数,以此创建对象实例。
  • this不同:箭头函数的this指向于它父级的this,在普通函数中,this 总是指向调用它的对象,如果用作构造函数,它指向创建的对象实例。
  • arguments 对象:箭头函数没有arguments 对象,每一个普通函数调用后都具有一个

14. js 闭包是什么?有什么优缺点?

  • 闭包
    • 闭包就是内层函数可以访问外层函数内部数据的函数
  • 优点
    • 延长了变量的生命周期、缓存数据、避免全局污染
  • 缺点
    • 增加常驻内存, 容易造成内存泄漏

标签:function,面试题,name,前端,基础,原型,函数,父类,构造函数
From: https://www.cnblogs.com/6-2-1/p/16736779.html

相关文章

  • 前端重点复习笔记
    JavaScriptJS特点不主动开启新的线程的情况下单线程如何开启新线程varworker=newWorker('js文件路径')js是弱类型语言所有的声明都是通过var在赋值的时......
  • 前端生成二维码
    往常我们二维码可能都是后端去处理,构建一个image对象,最后输出image二进制流,然后前端定义一个img控件去展示。但这有个弊端,就是流传输的比较大,当流量大的时候,不仅浪费流量......
  • CSS基础(基于黑马程序员视频的学习笔记)
    一、CSS选择器1、标签选择器选中所有的该标签标签名{CSS属性名:属性值;}2、类选择器.类名{CSS属性名:属性值;}所有标签都有class属性,class属性的属......
  • 【前端必会】使用indexedDB,降低环境搭建成本
    背景学习前端新框架、新技术。如果需要做一些数据库的操作来增加demo的体验(CURD流程可以让演示的体验根据丝滑)最开始的时候一个演示程序我们会调用后台,这样其实有一点弊......
  • 软件测试基础
    软件是控制计算机硬件工作的工具  软件产生过程:1.需求产生(需求方、产品经理)2.需求文档(产品经理)3.设计效果图(UI设计师)4.产品开发(研发人员)5.产品测试(测试人员)6.......
  • 前端三件套 HTML+CSS+JS基础知识内容笔记
    HTML基础目录HTML基础HTML5标签doctype标签html标签head标签meta标签title标签body标签文本和超链接标签标题标签段落标签换行标签水平标签强调标签图片标签与超链接标签......
  • C++语言程序设计基础 内联函数
    C++内联函数是通常与类一起使用。如果一个函数是内联的,那么在编译时,编译器会把该函数的代码副本放置在每个调用该函数的地方。对内联函数进行任何修改,都需要重新编译函数......
  • 代码狗必看:前端开发3大坑
    0x0000 第一大坑:浏览器兼容性第一次浏览器大战桌面端浏览器大战的硝烟尚未散尽,移动端纷争又起。大厂神仙打架,码农苦不堪言。各种CSS、JS不兼容,坑得码农尽白头。在兼容性这......
  • 前端开发工程师
    精通前端,熟悉后端5年工作经验,编写艺术般的代码,做好现在,技术只是为了改变生活!专业技能·Web·IT行业的学习需要持之以恒,知识深度与广度都很重要。而前端开发......
  • 前端加密算法之MD5
    1、简介1.1、隶属于单向加密算法1.2、不可逆的加密算法、不能从密文反推出明文,除非做碰撞测试1.3、一种摘要算法、哈希算法、散列算法(通过一个函数,把任意......