> 文章列表 > 面试准备ing

面试准备ing

面试准备ing

  • 参考文档
    • DOM特性1
    • HTML5特性2
    • JavaScript以函数对象为核心,函数又称为first-calss objectsfirst-class citizens
  • JS基础面经巩固
    • 路由原理,为什么要使用路由3,有hash为什么还要history?

      路由用于设定访问路径,并将路径和组件映射起来。路由的本质就是建立url和页面之间的映射关系。

      1. hash
        URI4 中的 fragment 用来标识次级资源,https://domain/index#L18,L18是fragment的值。fragment 的改变不会触发浏览器刷新页面,但是会生成浏览历史。
        • 单页面路由,通过location.hash操作URI的fragment,可通过HashChange事件监听fragment变化
        • HTML锚点,页面内定位,将页面滚动到该锚点的位置
        • fragment会被谷歌浏览器忽略,使用hash的应用SEO效果不友好
        • 支持回车刷新
        • 对低版本支持度更好
      2. history
        • hash本来是做页面内定位的,如果将其用于路由,原来的锚点功能就不能使用了。history模式不仅可以在url放参数,还可以将数据存放在一个特定的对象中。
        • 回车刷新错误
        • 切换,gobackforward
        • 修改历史状态
        • 不会刷新路由
      3. 前端路由出现面向的需求
        • 路由就是根据不同的url地址来展示不同的页面或内容的功能
    • hook为什么不可以出现在控制语句中,为什么要用链表或者数组,用别的数据结构可以吗?

      Vue3 Hooks函数实现原理

      • 将各个生命周期的函数挂载或者注册到组件实例上,等到组件运行到某个时候,再去组件实例上把对应的生命周期的函数取出来执行,其生命周期的执行过程和Vue Scheduler相关。
      • createHook是一个闭包函数,通过闭包获取组件实例相关状态,其底层是调用injectHook函数。挂载过程是同步的,但是onMounted函数执行是异步的,通过异步执行 onMounted 能够确保所有的节点已经全部挂载完毕。
      // packages/runtime-core/src/apiLifecycle.ts
      export function injectHook(type, hook, target) {if(target) {// 把各个生命周期的Hooks函数挂载到组件实例上,并且是一个数组,因为可能你会多次调用同一个组件的同一个生命周期函数const hooks = target[type] || (target[type] = [])// 把生命周期函数进行包装并且把包装函数缓存在__weh上const wrappedHook =hook.__weh ||(hook.__weh = (...args: unknown[]) => {if (target.isUnmounted) {return}// 当生命周期调用时 保证currentInstance是正确的setCurrentInstance(target)// 执行生命周期Hooks函数const  res = args ? hook(...args) : hook()unsetCurrentInstance()return res})// 把生命周期的包装函数绑定到组件实例对应的hooks上hooks.push(wrappedHook)// 返回包装函数return wrappedHook}
      }
      
      • hooks不能出现在控制语句中原因
        a. hooks为了在组件中引入状态,引入了有序表或数组
        b. 函数本身不能保存状态,我们需要额外维护一个有序的表,在执行 useState 之类的 hook 时,将它们保存到这个表里,这要求每次函数组件的 hook 执行的位置相同,数量正确
    • 网络

      DNS域名解析过程:

      1. 检查浏览器缓存
      2. 检查操作系统缓存
      3. 检查路由器缓存
      4. 若无,向ISP的LDNS服务器查询
      5. 若无,向根域名服务器请求解析

      CDN工作原理:

      1. DNS对域名进行解析得到IP
      2. 浏览器发送数据请求
      3. 服务器向浏览器返回响应数据
    • 性能优化

      加载:延迟加载、按需加载,在长网页中延迟加载图片数据,是一种较好的网页性能优化的方式。在滚动屏幕之前,可视化区域之外的图片不会进行加载,在滚动屏幕时才加载。
      原理:使用HTML5 的data-xxx属性来储存图片的路径,在需要加载图片的时候,将data-xxx中图片的路径赋值给src,这样就实现了图片的按需加载,即懒加载

      <script>
      var imgs = document.querySelectorAll('img');
      function lozyLoad(){var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;var winHeight= window.innerHeight;for(var i=0;i < imgs.length;i++){if(imgs[i].offsetTop < scrollTop + winHeight ){imgs[i].src = imgs[i].getAttribute('data-src');}}
      }
      window.onscroll = lozyLoad();
      </script>
      

      预加载:将所需的资源提前请求加载到本地,这样后面在需要用到时就直接从缓存取资源。
      原理:使用HTML5 的data-xxx属性来储存图片的路径,在需要加载图片的时候,将data-xxx中图片的路径赋值给src,这样就实现了图片的按需加载,即懒加载

    • 回流与重绘

      回流触发:1. 全局范围 2. 局部范围

      • 页面首次渲染
      • 浏览器的窗口大小发生变化
      • 元素的尺寸或者位置发生变化
      • 元素的字体大小发生变化
      • 激活CSS伪类
      • 添加或者删除可见的DOM元素

      重绘:元素样式发生改变,但元素在文档流中的位置未发生改变

      • color、background 、background-color、background-image 、outline 、outline-color、outline-width 、text-decoration、border-radius、visibility、box-shadow

      性能提升:

      • 操作低层级的DOM节点进行操作
      • table布局易重新布局
      • 原生css表达式
      • 不要频繁操作元素的样式,更改类名
      • 使用 absolute 或 fixed
      • display: none隐藏元素
      • DOM操作放一起执行
    • 防抖与节流

      • 函数防抖5是指在事件被触发 n 秒后再执行回调,如果在这 n 秒内事件又被触发,则重新计时。这可以使用在一些点击请求的事件上,避免因为用户的多次点击向后端发送多次请求。
      • 函数节流6是指规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。节流可以使用在 scroll 函数的事件监听上,通过事件节流来降低事件调用的频率。
    • Web Worker“多线程”技术7

      • 在 HTML5 的新规范中,实现了 Web Worker 来引入 JavaScript 的 “多线程” 技术,他的能力让我们可以在页面主运行的 JavaScript 线程中加载运行另外单独的一个或者多个 JavaScript 线程;
      • Web Worker 提供的多线程编程有以下几个特点
        1. 主程序线程和 Worker 线程之间,Worker 线程之间不会共享任何作用域或资源
        2. 通信方式:基于事件监听机制的message
        3. 对于 JavaScript 语言,Web Worker 只是浏览器(宿主环境)提供的一个能力/API
        4. Web Worker 的实现为前端程序带来了后台计算的能力,可以实现主 UI 线程与复杂计运算线程的分离,从而极大减轻了因计算量大而造成 UI 阻塞而出现的界面渲染卡、掉帧的情况,并且更大程度地利用了终端硬件的性能;
    • 用户访问网址浏览器执行的过程

      • 域名查询DNS,本设备->路由器缓存->ISP网络服务商->根节点
      • 浏览器做出界面响应
      • DOM Tree解析、CSS Tree解析【如遇到JS脚本节点,停止HTML和DOM构建->执行请求得到的JS脚本】
      • JS请求,DOM停止解析
      • 对DOM + CSS Tree生成布局,执行JS操作布局
      • 监控事件队列,一次只能处理其中的一个事件(响应界面交互)【此时才进行事件队列的创建】
        • 浏览器事件、网络事件、用户事件、计时器事件
    • 函数声明和函数表达式

      • function fn{} 因为函数会有提升,声明之前调用并不会出错
      • var fn = function() {}; fn();函数表达式的函数名可要可不要,但是函数表达式的调用一定是在赋值之后,不然之前调用会引发错误

  1. https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model ↩︎

  2. https://developer.mozilla.org/en-US/docs/Glossary/HTML5 ↩︎

  3. 路由方便我们对大型应用进行集成管理,逻辑切换以及权限管理等,尤其是针对三维应用,可以借助对应的生命周期函数实现对应的切换效果,及时的关闭和销毁对应的三维实体。 ↩︎

  4. Uniform Resource Identifier 统一资源标识符 ↩︎

  5. 按钮提交场景:防⽌多次提交按钮,只执⾏最后提交的⼀次。服务端验证场景:表单验证需要服务端配合,只执⾏⼀段连续的输⼊事件的最后⼀次,还有搜索联想词功能类似⽣存环境请⽤lodash.debounce ↩︎

  6. 拖拽场景:固定时间内只执⾏⼀次,防⽌超⾼频次触发位置变动。缩放场景:监控浏览器resize。动画场景:避免短时间内多次触发动画引起性能问题 ↩︎

  7. https://zhuanlan.zhihu.com/p/25184390 ↩︎