前端学习笔记

Posted by 呆贝斯 on April 25, 2022

HTML/CSS/JS

  1. 请谈谈你对HTML5和CSS3新特性的理解。你在实际项目中如何运用这些新特性? HTML5新出了许多语义化标签(nav,header,main等)和API(canvas,webGL),语义化标签优点在于提高代码可读性和可维护性, 有利于搜索引擎更容易读懂(seo),有些特殊的屏幕阅读器可以通过分析语义化标签进行展示(比如盲人阅读器)。 CSS3新出了圆角,阴影,过渡,动画,弹性布局等使创造复杂样式和交互变得更简单,也使我们可以更快的去完成页面样式。

  2. 请解释一下JavaScript中的闭包(closure),并给出一个闭包的应用场景。 闭包是指函数有权访问其作用域以外的变量,这就叫闭包,闭包有两种表现形式,一种是函数作为参数传递,一种是函数作为返回值, 闭包的应用场景有防抖节流函数、setTimeout、封装私有变量。闭包的缺点在于,其访问的变量不会被回收(会一直占用内存), 所以会造成内存泄漏。

  3. 请简述原型链(prototype chain)的概念,以及它在JavaScript中的应用。 原型链是js的一种继承方式,每个对象都有自己的__proto__属性指向其构造函数的prototype属性, 当对象调用某个方法且对象里并没有定义这个方法时就会通过__proto__去寻找这个方法, 如果其__proto__没有就会顺着其__proto__的__proto__就是顺着其原型链去寻找方法直到null。

  4. 请解释一下Event Loop(事件循环)机制以及它在JavaScript中的作用。 Event Loop是js实现异步的一种机制,它让js这个单线程语言可以实现并发操作。JavaScript引擎在执行栈为空时, 会从任务队列中取出任务执行;任务队列有两类。
    • 宏任务:包括script(整个代码)、setTimeout、setInterval、setImmediate和I/O等。
    • 微任务:Promise、process.nextTick等
    • 先执行宏任务再执行微任务
  5. 请解释一下JavaScript的同步和异步,以及如何使用Promise、async/await处理异步操作。 js是一个单线程语言,所以会同步执行代码,为了防止代码阻塞,通过时间循环机制实现了代码异步处理,当同步代码都执行完毕之后, 再去执行异步代码,常见的异步代码有网络请求、alert、setTimeout等,promise是异步的解决方案, 它解决了之前通过回调函数实现异步而产生的回调地狱的问题,promise有三种状态,pendding、reject、fulfilled, 只能从pedding到其他状态,且过程不可逆,async和await是基于promise实现的,它是为了让异步代码看起来像同步代码, 使代码更容易阅读和维护。

Vue/React

  1. 你在实际项目中如何使用Vue全家桶(Vue-router、Vuex等)?请分享一下你的经验。 我通过vue-router进行路由管理,通过Vuex管理全局状态,我会对路由进行懒加载,通过ES6的import,当然也可以用vue的动态组件, Vuex的核心包括state、getter、mutation和action,通过mutation去更改state的值,要注意异步操作只能放在action里。

  2. 请谈谈你对Vue的生命周期钩子函数的理解以及常见的应用场景。 vue的组件的生命周期包括组件创建、组件挂载、组件更新、组件销毁,从中产生了生命周期钩子函数。 vue2中包括 beforeCreate、created、beforeMounte、Mouted、beforeUpadte、updated、beforeDestory、destroyed, 如果组件使用了keep-alive进行缓存的话,还会有active、deactive。

    vue3中的生命周期包括setup,onBeforeMount、onMounted、onBeforeUpdate,onUpdatedon、onBeforeUnmount、onUnmounted。

    mouted(onMounted)钩子函数可以做一些关于dom的操作,beforeDestroy(BeforeUnmount)在此阶段可以执行清理工作, 如移除事件监听器、取消计时器等。

  3. 请描述一下Vue中的计算属性(computed property)和侦听属性(watch property)以及它们的区别和应用场景。 计算属性是依赖其他属性变化得出结果,而侦听属性是针对数据变化而触发操作,计算属性具有缓存机制。

生产

  1. 在你的项目中,你是如何处理跨域请求的? 因为浏览器的同源策略(ip,端口,协议需要一致),我们跨域请求的时候会出现跨域问题, 在开发环境中,我使用代理服务器(如vue.config.js中的proxy配置)解决跨域问题。 在生产环境中,我是用nginx的代理解决跨域问题。当然也可以让后端在服务器端设置响应头, 允许跨域请求。或者是用websocket,websocket没有跨域问题。

  2. 在你的项目中,你是如何处理浏览器兼容性问题的? 处理浏览器兼容性问题,我会使用autoprefixer自动添加CSS前缀,使用Babel转译新语法,使用Polyfill补充缺失功能, 并针对特定浏览器进行特殊处理。

  3. 请解释一下HTTP缓存机制,以及如何在项目中利用HTTP缓存提高性能? http缓存包括强缓存和协商缓存

    • 强缓存:浏览器自己的缓存策略
    • 强缓存是通过Cache-Control字段来控制的,值有max-age(缓存的最大时间)、no-cache(无需强制缓存)、no-store(服务端直接返回)
    • 协商缓存:由服务器判断资源是否一样,一致则返回304,否则返回200和最新资源

    判断资源是否一致,这主要通过Last-Modified/If-Modified-Since和ETag/If-None-Match头部字段实现。 Last-Modified:资源最后修改时间。If-Modified-Since:客户端下次请求相同资源时,会发送该字段, 值为上次收到的Last-Modified的值。ETag:资源的唯一标识 If-None-Match:客户端下次请求相同资源时, 会发送该字段,值为上次收到的ETag值。

  4. 请谈谈你对响应式设计(Responsive Design)的理解以及如何在项目中实现响应式设计。 响应式设计就是指让网站在不同设备下实现自适应展示,实现响应式设计有以下几种方法:
    • 不使用固定单位使用相对单位,如百分比,rem,vw/vh等
    • 尽可能的使用弹性布局
    • 媒体查询:针对不同的屏幕尺寸,修改对应的css
  5. 在JavaScript中,谈谈你对作用域和作用域链的理解。 作用域是指变量和函数的可访问的上下文,就是其作用域,作用域链是由指变量或函数查找时先从当前的执行上下文往其夫级的上下文寻找, 直到最外层的window。

优化

  1. 请谈谈你对前端性能优化的理解,以及在项目中采取了哪些措施来提升性能? 前端性能优化分为两类,一种是让文件加载更快,另一种是让文件渲染更快。
    • 加载更快的方法 让传输的数据包更小(压缩文件/图片):图片压缩和文件压缩 减少网络请求的次数:雪碧图/精灵图、节流防抖 减少渲染的次数:缓存(HTTP缓存、本地缓存、Vue的keep-alive缓存等) 使用CDN:利用内容分发网络(Content Delivery Network)加速静态资源的加载速度,将资源部署到离用户更近的服务器
    • 文件渲染更快的方法 提前渲染:ssr服务器端渲染 避免渲染阻塞:CSS放在HTML的head中 JS放在HTML的body底部 避免无用渲染:懒加载 减少渲染次数:对dom查询进行缓存、将dom操作合并、减少重排重绘
  2. 请谈谈您对于前端开发中代码规范和项目管理的理解,以及您在实际工作中如何保证高质量的代码输出。 前端代码规范和项目管理在前端开发中非常重要,他可以保证代码风格一致,提高代码可读性,提高项目可维护性和团队协作效率。 在实际工作中我使用如下内容保证高质量的代码输出。
    • 统一的编码风格:用代码风格指南和自动化工具(如ESLint、Prettier等)
    • 使用版本控制系统:通过git来管理代码
    • 注释和文档:编写清晰明了的readme.md
    • Code Review:团队成员对代码进行代码审查