1. 请说一说 JavaScript 中闭包的概念以及它的作用
查看答案
闭包是 JavaScript 中一个重要的概念,它允许函数在定义时访问其外部函数的变量和参数。闭包的作用是:
- 实现私有变量,保护数据的安全性和隐私性。
- 可以让函数的变量值始终保持在内存中,延长变量的生命周期。
- 可以模拟块级作用域,在 JavaScript 缺乏块级作用域的情况下实现类似的效果。
2. 谈谈你对 Vue 组件通信方式的理解
查看答案
Vue 父子组件通信:- 父组件向子组件传值:使用 props 。父组件在使用子组件时,通过属性的形式将值传递给子组件。需要注意的是,props 可以进行类型校验(如字符串、数字、对象、数组等),以确保传递的值符合预期。同时,如果传递的是对象或数组,当父组件中的数据发生变化时,子组件中的 props 值不会自动响应,除非进行特殊处理。
- 子组件向父组件传值:通过自定义事件 emit 。子组件在内部使用 this.$emit('自定义事件名', 传递的数据) 来触发事件,并将数据传递给父组件。父组件在使用子组件时,通过 @自定义事件名="处理函数" 来接收子组件传递的数据,并进行相应的处理。 非父子组件通信:
- Vuex :是一个集中式的状态管理库,适用于大型复杂的应用。它将应用的状态集中管理,使得多个组件可以共享和修改状态,并且状态的变化是可追踪和可预测的。
- Pinia :也是一个状态管理库,相比 Vuex 更加简洁和现代化,提供了类似的状态共享和管理功能。
- provide / inject :这对选项允许一个祖先组件向其所有子孙后代组件注入数据。祖先组件使用 provide 提供数据,子孙组件使用 inject 来接收数据。但要注意,这种方式提供的数据不是响应式的,除非数据本身是响应式对象。
3. Vue 中的计算属性(computed)和侦听器(watch)有什么区别
查看答案
计算属性(computed):- 基于已有的响应式数据进行计算,返回一个新的派生值。
- 具有缓存特性,只有在其依赖的数据发生变化时才会重新计算。
- 通常用于对多个相关数据进行简单的计算和格式化输出。
- 计算属性默认只有 getter 方法,当需要时可以定义 setter 方法来实现双向绑定。
4. 请简述 Vuex 的核心概念和使用场景
查看答案
Vuex 的核心概念包括 State(存储应用的状态数据)、Mutations(用于更改状态,且是同步操作)、 Actions(用于处理异步操作,并通过提交 Mutations 来更改状态)、 Getters(用于从 State 中派生计算属性) 和 Modules(用于将大型的状态管理拆分成多个模块)。- State 用于存储应用的状态数据,是单一数据源。
- Mutations 用于更改状态,并且必须是同步操作,以保证状态更改的可追踪性和可预测性。
- Actions 用于处理异步操作,如网络请求等,然后通过提交 Mutations 来最终更改状态。
- Getters 可以从 State 中派生计算属性,方便组件获取经过处理或计算后的状态数据。
- Modules 可以将大型的状态管理按照功能模块进行拆分,使状态管理更加清晰和可维护。
5. 解释一下 CSS 盒模型,以及在不同浏览器中的差异
查看答案
在CSS中,每个元素都被一个“盒子”所包围。盒子类型分为行盒和块盒,行盒的宽高由其内容决定,无法直接设定宽高;块盒则可以自由设定宽高。 盒模型分为标准盒模型和怪异盒模型(也称为IE盒模型)。标准盒模型中,元素的宽度和高度仅包括内容部分,不包含内边距(padding)、边框(border)和外边距(margin);而怪异盒模型中,元素的宽度和高度包含了内容、内边距和边框。 在现代的 Chrome 内核浏览器中,默认使用标准盒模型;在传统的 IE 内核浏览器中,默认使用怪异盒模型。 我们可以通过设置box-sizing: border-box;
来将盒模型的类型更改为怪异盒模型,使其计算宽度和高度时包含内边距和边框。
6. 谈谈你对 HTML5 语义化标签的理解和应用
查看答案
HTML5 语义化标签是指在HTML5中使用语义化的标签,这些标签能够更好地描述网页的内容和结构,从而提高网页的可读性、可维护性和可访问性。 HTML5 语义化标签包括:-
<header>
:用于定义页面的头部区域,通常包含网站名称、导航菜单等。 -
<nav>
:用于定义导航区域,通常包含网站导航菜单。 -
<main>
:用于定义页面的主内容区域,通常包含文章、表格、图像等。 -
<article>
:用于定义独立的文章或内容片段,通常包含文章标题、作者、发布日期等。 -
<section>
:用于定义页面的章节区域,通常包含文章、表格、图像等。 -
<aside>
:用于定义页面的侧边栏区域。 -
<footer>
:用于定义页面的底部区域,通常包含版权信息、联系信息等。
7. 实现一个简单的发布/订阅模式(Pub/Sub)的 JavaScript 代码
查看答案
class EventEmitter { constructor() { this.events = {}; } on(eventName, callback) { if (!this.events[eventName]) { this.events[eventName] = []; } this.events[eventName].push(callback); } emit(eventName, ...args) { if (this.events[eventName]) { this.events[eventName].forEach(callback => callback(...args)); } } }
8. 如何优化 JavaScript 代码的性能
查看答案
- 代码压缩和混淆:通过工具如 Webpack 或 Gulp 对代码进行压缩和混淆,可以减小文件体积,加快下载和解析速度。
- 缓存策略:利用浏览器的缓存机制,为静态 JavaScript 文件设置合适的缓存头,避免重复下载。
- 避免不必要的计算:在可能的情况下,提前计算或缓存计算结果,避免在关键路径上进行复杂的计算。
- 选择合适的数据结构和算法:根据具体的业务需求,选择效率更高的数据结构(如 Map 对比 Object)和算法。
- 避免全局变量:过多的全局变量可能导致命名冲突和意外的修改,尽量使用局部变量或模块模式。
- 事件委托:当处理大量相似元素的事件时,使用事件委托可以减少事件处理函数的数量,提高性能。
9. 如何实现图片懒加载?
查看答案
- 设置图片的 data-src 属性:
将图片的实际地址存储在
data-src
属性中,而初始的src
属性可以设置为一个占位图片或空白。 - 监听滚动事件: 当页面滚动时,计算图片是否进入可视区域。如果进入,则将 data-src 的值赋给 src ,触发图片加载。
- 使用 IntersectionObserver API:
创建
IntersectionObserver
对象,配置其回调函数。当被观察的图片元素进入或退出视口时,回调函数会被触发,从而进行图片的加载操作。 - 利用loading="lazy"属性(HTML5 特性):
在
<img>
标签中添加loading="lazy"
属性,浏览器会在适当的时候自动加载图片。 - 预加载策略: 对于即将进入视口的图片,可以提前进行预加载,提高加载的响应速度。
- 延迟加载: 除了视口判断,还可以根据用户的操作行为或页面的加载进度来决定图片的加载时机,例如在页面完全加载一段时间后再加载非关键图片。
- 图片压缩和优化: 在保证图片质量的前提下,对图片进行压缩处理,减小图片的大小,加快加载速度。
- 服务端处理: 在服务端根据请求的上下文和用户信息,有针对性地返回不同分辨率或尺寸的图片,以适应不同的网络环境和设备。
10. 请谈谈CSS选择器优先级规则
查看答案
- ID 选择器:通过元素的 id 属性进行选择,例如
#myElement
。 - 类选择器:基于元素的 class 属性进行选择,例如
.myClass
。 - 标签选择器:直接选择指定的 HTML 标签,例如
div
、p
等。 - 属性选择器:根据元素的属性及其值进行选择,例如
[type="text"]
。 - 伪类选择器:根据元素的特定状态进行选择,例如
:hover
(鼠标悬停时)、:active
(被激活时)、:focus
(获取焦点时)等。
特殊性:ID选择器:(1,0,0),类选择器:(0,1,0),标签选择器:(0,0,1)。
当多个选择器同时作用于一个元素时,其特殊性会按位相加。特殊性值越大,优先级越高。如果特殊性相同,则后出现的样式声明会覆盖先出现的。
欢迎在评论区留下您的见解~