js常见面试题

325 阅读4分钟

一、闭包(Closure)

闭包,没有明确的定义,每个人的理解都不一样。

MDN上面这样说的:闭包是一种特殊的对象。它由两部分构成:函数,以及创建该函数的环境。环境由闭包创建时在作用域中的任何局部变量组成。

简单来说,闭包就是指有权访问另一个函数作用域中的变量的函数。

产生一个闭包

创建闭包最常见的方式,就是在一个函数内部创建另一个函数。

function func(){
  var a = 1,b = 2;
  
  function closure(){
    return a+b;
  }
  return closure;
}

闭包的作用域链包含着它自己的作用域,以及包含它的函数的作用域和全局作用域。

匿名函数最大的用途是创建闭包,并且还可以构建命名空间,以减少全局变量的使用。从而使用闭包模块化代码,减少全局变量的污染。

按照我的理解 JavaScript 里面所有的函数都是闭包,因为有全局环境,所有的函数都可以访问全局变量。

一个闭包计算器

var countNumber = (function(){
  var num = 0;
  return function(){
    return ++num;
  };
})();

一个闭包面试题

function fun(n,o){
  console.log(o);
  return {
    fun: function(m){
      return fun(m,n);
    }
  };
}

var a = fun(0);  // ?
a.fun(1);        // ?        
a.fun(2);        // ?
a.fun(3);        // ?

var b = fun(0).fun(1).fun(2).fun(3);  // ?

var c = fun(0).fun(1);  // ?
c.fun(2);        // ?
c.fun(3);        // ?

undefined 0 0 0 undefined 0 1 2 undefined 0 1 1

二、函数的防抖(debounce)

  • 任务频繁触发的情况下,只有任务触发的间隔超过指定间隔的时候,任务才会执行。
function debounce(fn, wait) {
      let timeout = null;
      return function() {
        if(timeout!==null) clearTimeout(timeout);
        timeout = setTimeout(() => {
          fn.call(this, arguments);
        }, wait);
      };
    }

三、函数的节流(throttle)

  • 指定时间间隔内只会执行一次任务。
 function throttle(fn, wait) {
      let canRun = true;
      return function() {
        if(!canRun) return;
        setTimeout( () => {
          fn.call(this, arguments);
          canRun = true;
        }, wait);
      };
    }

四、重绘(repaint)与回流(reflow)

  • 重绘:当元素样式的改变不影响布局时,浏览器将使用重绘对元素进行更新,此时由于只需要UI层面的重新像素绘制,因此损耗较小。 常见的重绘有:
  1. color
  2. background
  • 回流:当元素的尺寸、结构或者触发某些属性时,浏览器会重新渲染页面,称为回流。此时,浏览器需要重新经过计算,计算后还需要重新页面布局,因此是较重的操作。 -常见的回流有:
  1. 页面初次渲染
  2. 浏览器窗口大小gaibai
  3. 元素尺寸/位置/内容发生改变
  4. 元素字体大小变化
  5. 添加或删除可见的DOM
  6. 激活css伪类

回流必定重绘,重绘不一定回流。重绘开销小,回流开销大。

  • 总结:
  1. 避免频繁操作样式,可汇总后统一一次修改
  2. 尽量使用class进行样式修改,而 不是直接操作样式
  3. 减少dom操作

五、浏览器解析URL

  1. 用户输入URL地址。
  2. 对URL进行DNS域名解析(ip直接跳过)
  3. 建立TCP连接(三次握手)
  4. 浏览器发起http请求报文
  5. 服务器返回http请求报文
  6. 关闭tcp连接(四次挥手)
  7. 浏览器解析文档资源并渲染页面

三次握手 客户端:“喂,你听得到吗?” 服务端:“我听得到呀,你听得到我吗?” 客户端:“我能听到你,今天balabala……”

四次挥手 客户端:“你好,我这边没有数据要传了,我要关闭咯。” 服务端:“收到~我看一下我这边有没数据要传的。” 服务端:“我这边也没有数据要传啦,我们可以关闭连接咯~” 客户端:”ojbk~“

六、性能优化

web性能优化主要包括

  1. 度量标准
  2. 编码优化
  3. 静态资源优化
  4. 交付优化
  5. 构建优化
  6. 性能监控

度量标准

  • 首次有效绘制 当主要内容呈现在页面上
  • 英雄渲染时间 当用户最关心的内容渲染完成
  • 可交互时间 基本上用户可以点击UI并与其交互
  • 输入响应 界面响应用户输入所需的时间
  • 感知速度指数 测量填充页面内容的速度。 分数越低越好
  • 自定义

编码优化

  • 数据读取速度
    • 字面量与局部变量的访问速度最快,数组元素和对象成员相对较慢
    • 变量从局部作用域到全局作用域的搜索过程越长速度越慢
    • 对象嵌套的越深,读取速度就越慢
    • 对象在原型链中存在的位置越深,找到它的速度就越慢
  • DOM 减少dom操作
  • 流程控制 if-else 没有switch快 for in 因为能枚举到原型慢 forEach同理

静态资源优化

  • 文本文件压缩
  • 图片压缩

交付优化

  • 懒加载视频、图片等

构建优化

其他

css选择器的使用,

  • 保持简单,不要使用嵌套过多过于复杂的选择器。
  • 通配符和属性选择器效率最低,需要匹配的元素最多,尽量避免使用。
  • 不要使用类选择器和ID选择器修饰元素标签,如h3#markdown-content,这样多此一举,还会降低效率。
  • 不要为了追求速度而放弃可读性与可维护性。