JS面试题(1)

0 阅读5分钟

执行上下文

代码在执行期间运行的环境。存储变量和函数的地方,决定了变量和函数的可访问性。分为全局执行上下文[在代码被执行之前创建,全局变量和函数都在这里],函数执行上下文[函数被调用时会创建一个新的函数上下文,每个函数都有自己的独立上下文,包含函数的参数,局部变量和内部函数],eval[eval函数执行上下文]

在 JavaScript 中,执行上下文是栈形式的数据结构,它用来管理和控制代码的执行流程。当代码执行到一个函数时,会创建一个函数执行上下文并将其推入栈中,当函数执行完毕后,其上下文会从栈中弹出。

作用域和作用域链

作用域是变量可以使用的范围,分为全局作用域和局部作用句(函数作用域和块级作用域[es6])。是变量起作用的范围,定义的时候就已经确定了[静态作用域/词法作用域]。作用域链就是在作用域嵌套下,由内向外,层层访问形成的链式规则。

原型和原型链

每个函数都有的prototype属性叫原型,它是一个对象。每个对象都有一个__proto__属性,指向它构造函数的原型对象。

假设存在一个构造函数Person,只要是函数就存在一个prototype属性叫原型,可以把一些共享的属性和方法挂载到它身上。通过new Person创建一个person的实例对象,它其中就存在了一个__proto__隐式原型指向它构造函数的显示原型。在对对象的属性进行查找的时候,会在他自己对象上查找,然后到它构造函数的原型上查找。如果在构造函数的原型上也找不到,因为这个prototype也是一个对象也有一个__proto__对象指向它的父级的构造函数就会在它的父级的原型上查找,最后找到null,在查找的过程中就形成了一条链,就是原型链。

87b4889a-c3bd-43bd-8f37-c773806aa56e.png

闭包

一个能访问外部作用域变量的函数。

通常以函数嵌套的方式存在,即一个函数嵌套另一个函数,函数内部能访问到函数外部的变量,这就形成了闭包。

闭包可以在私有化变量的基础上保持数据。

防抖节流函数就应用到了数据保持这个特性。

在防抖函数中,对按钮进行点击的时候,会定义一个time定时器。如果不采用闭包,那么下一次点击的时候会重新生成一个新的定时器,两个定时器的引用不同,是没有关联的。使用闭包的话我们可以在内存中直接找到之前创建的定时器,调用就可以拿到对应定时器的时间进行操作。

闭包容易造成内存泄漏,所以在最后要对定时器进行及时的清空。

// 防抖函数
// 将多次触发的函数合并成一次触发
function debounce(fn, delay){
  let time = null;
  return function(){
    if(timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(() => {
      fn.call(this, arguments);
      timer = null;
    }, delay)
  }

}

浏览器输入到页面渲染的流程

DNS解析 → TCP连接 → 发送请求 → 服务器处理请求 → 发送响应 → 接受响应 → 解析文档 → 加载资源 → 渲染页面 → 执行javascript → 加载完成

浏览器接收url并开启一个新进程(这一部分可以展开浏览器的进程与线程的关系) 浏览器解析输入的 URL,提取出其中的协议、域名和路径等信息。(这部分涉及URL组成部分)

浏览器向 DNS 服务器发送请求,DNS服务器通过 多层查询 将该 域名 解析为对应的 IP地址 ,然后将请求发送到该IP地址上,与 服务器 建立连接和交换数据。(这部分涉及DNS查询)

浏览器与服务器建立 TCP 连接。(这部分涉及TCP三次握手/四次挥手/5层网络协议) 浏览器向服务器发送 HTTP 请求,包含请求头和请求体。(4,5,6,7包含http头部、响应码、报文结构、cookie等知识)

服务器接收并处理请求,并返回响应数据,包含状态码、响应头和响应体。

浏览器接收到响应数据,解析响应头和响应体,并根据状态码判断是否成功。

如果响应成功,浏览器接收到http数据包后的解析流程(这部分涉及到html - 词法分析,解析成DOM树,解析CSS生成CSSOM树(样式树),合并生成render渲染树(样式计算)。然后layout布局,分层,调用GPU绘制等,最后将绘制的结果合成最终的页面图像,显示在屏幕上。这个过程会发生回流和重绘)。

连接结束 -> 断开TCP连接 四次挥手

浏览器页面加载机制

解析html构建DOM树,解析CSS构建CSS树,合并DOM树和CSS树生成渲染树。布局render tree进行布局计算。执行javascript代码更新DOM tree 和CSS tree。重绘和回流。