前端面试题详解整理20|重绘与重排的区别,闭包CDN原型与原型链,响应式的布局Vue2 与 Vue3 的区别, Vue 的响应式原理, JavaScript 与

63 阅读14分钟

base深圳 新旦智能 前端实习面经

投递渠道:BOSS

面试时间: 2024-02-19

  1. 自我介绍与实习经历

  2. 实习中的性能优化是如何做的

  3. 日常中遇到问题, 你会通过哪些渠道去解决

  4. 重绘与重排的区别 重绘(Repaint)和重排(Reflow)是浏览器渲染页面时的两个重要概念,它们的区别如下:

  5. 重绘(Repaint)

    • 重绘指的是当 DOM 元素样式改变,但是它的布局不受影响,只需要重新绘制元素的内容,而不会影响到其他元素的位置或大小。
    • 典型的重绘操作包括修改元素的颜色、背景色、文字样式等。
    • 重绘操作的代价相对较小,因为它不需要重新计算元素的布局信息,只需要更新元素的视觉样式即可。
  6. 重排(Reflow)

    • 重排指的是当 DOM 元素的尺寸、位置或者结构发生变化时,浏览器需要重新计算元素的几何属性(包括大小、位置和布局等),并且更新页面的布局。
    • 典型的重排操作包括修改元素的宽度、高度、边距、内边距、定位属性等,以及插入、删除或移动 DOM 元素等。
    • 重排操作会影响到页面的布局结构,可能导致其他元素的重新排列和重绘,从而造成性能上的损失。

重绘和重排是渲染引擎优化的重点对象。为了提高页面性能,尽量减少重排和重绘的次数是很重要的。通常可以通过以下方法来减少重排和重绘的发生:

  • 尽量使用 CSS3 中的 transform 和 opacity 属性来替代 top、left、width、height 等属性的改变,因为它们不会触发重排和重绘。
  • 将需要多次重排和重绘的 DOM 操作合并为一次操作。
  • 使用文档碎片(DocumentFragment)来高效地操作 DOM。
  • 将需要频繁访问的 DOM 属性缓存起来,减少重复计算。
  • 将样式表放在页面的头部,减少样式表加载的时间。
  • 使用 CSS3 动画代替 JavaScript 动画,因为 CSS3 动画可以由 GPU 加速。
  1. Vue2 与 Vue3 的区别 Vue.js 3 是Vue.js的最新版本,与Vue.js 2相比有许多改进和新特性。以下是Vue.js 3相对于Vue.js 2的一些主要区别:

  2. 性能优化

    • Vue.js 3通过重写虚拟DOM的实现,提高了渲染性能。新的编译器和静态分析器使得编译速度更快。
    • Vue.js 3引入了Proxy来替代Vue.js 2中的Object.defineProperty,提供了更好的响应性能。
  3. Composition API

    • Vue.js 3引入了Composition API,允许开发者将组件的逻辑按照功能进行组织,而不是按照选项的方式。这使得代码更易于维护和理解。
    • Composition API提供了更灵活的组件复用和逻辑复用方式,使得组件更加可组合和可测试。
  4. TypeScript支持

    • Vue.js 3对TypeScript的支持更加友好,包括内置的TypeScript支持、更好的类型推断、更好的类型检查等。这使得在使用TypeScript进行开发时更加方便和安全。
  5. 模块化架构

    • Vue.js 3采用了更加模块化的架构,将不同功能拆分成独立的模块,使得整个框架更加灵活和可维护。
  6. Tree-shaking支持

    • Vue.js 3对Tree-shaking的支持更好,通过模块化的架构和静态分析,可以更有效地删除未使用的代码,减少包的体积。
  7. 全局API的改变

    • Vue.js 3中对一些全局API进行了改变,例如全局API的调用方式和参数的变化等。
  8. 生命周期钩子的改变

    • Vue.js 3中对一些生命周期钩子进行了改变,例如引入了beforeUnmount钩子替代了beforeDestroy钩子,添加了onRenderTracked和onRenderTriggered钩子等。
  9. Composition API对比Options API

    • Vue.js 2使用的是Options API,而Vue.js 3引入了Composition API。Composition API可以更灵活地组织组件的逻辑,使得代码更易于维护和理解。

总的来说,Vue.js 3相对于Vue.js 2在性能、开发体验、功能扩展和TypeScript支持等方面都有所改进和优化,是Vue.js的一个重要升级版本。

5. Vue 的响应式原理

Vue的响应式原理是Vue.js框架的核心之一,它使得数据的变化能够自动地反映在视图上,从而实现了数据驱动视图的双向绑定。下面是Vue的响应式原理的简要解释:

  1. 数据劫持: 当创建Vue实例时,Vue会对data选项中的数据进行劫持,即通过Object.defineProperty()或ES6的Proxy对象来监听数据的变化。

  2. 依赖追踪: Vue会为每一个被劫持的属性维护一个依赖列表,当属性被访问时,会将当前的Watcher(观察者)对象添加到依赖列表中。

  3. 响应式触发: 当数据发生变化时,Vue会通过触发Setter方法来通知所有相关的Watcher对象,告诉它们数据发生了变化。

  4. 更新视图: Watcher收到数据变化的通知后,会调用更新函数(例如组件的render函数),从而更新视图。这样就实现了数据的变化自动反映在视图上的效果。

总的来说,Vue的响应式原理通过数据劫持、依赖追踪和更新视图的方式,实现了数据与视图之间的双向绑定。当数据发生变化时,Vue能够自动地更新相关的视图,从而提高了开发效率和用户体验。

7. 如何理解响应式布局, 如何实现响应式的布局

响应式布局是指网页布局能够根据用户设备的屏幕大小、分辨率和方向等因素进行自适应调整,以实现在不同设备上具有良好的显示效果和用户体验。实现响应式布局可以通过以下方式来理解和实现:

  1. 媒体查询(Media Queries): 媒体查询是CSS3的一个重要特性,可以根据不同的媒体类型和媒体特性来应用不同的样式。通过在CSS中使用@media规则,可以根据设备的特性(如屏幕宽度、高度、方向等)来应用不同的样式,从而实现响应式布局。

  2. 流式布局(Fluid Layout): 流式布局是指布局中的元素尺寸是相对于视口宽度或父容器宽度的百分比。通过设置元素的宽度、高度、边距和内边距等样式为百分比值,可以使得布局中的元素在不同设备上具有一定的弹性,从而实现响应式布局。

  3. 弹性布局(Flexbox Layout): Flexbox是CSS3的一种布局模式,可以更加灵活地控制容器中的子元素的排列方式、对齐方式和尺寸分配等。通过使用Flexbox布局,可以实现在不同设备上更加灵活和方便地布局页面,适应不同的屏幕大小和方向。

  4. 栅格系统(Grid System): 栅格系统是一种将页面分割成行和列的布局方式,可以通过设置不同的列宽和偏移量来实现页面的布局。通过使用响应式的栅格系统,可以在不同设备上实现灵活的布局调整,从而适应不同的屏幕大小和分辨率。

  5. CSS预处理器(CSS Preprocessor): 使用CSS预处理器(如Sass、Less等)可以更加方便地管理和维护样式表,并且提供了一些便捷的工具和功能,如变量、混合、嵌套等。通过结合CSS预处理器和响应式布局的技术,可以更加高效地实现复杂的响应式布局效果。

综上所述,实现响应式布局可以通过媒体查询、流式布局、弹性布局、栅格系统和CSS预处理器等方式来实现,从而确保网页在不同设备上具有良好的显示效果和用户体验。

9. 原型与原型链的理解

原型(Prototype)和原型链(Prototype Chain)是JavaScript中的重要概念,用于实现对象的继承和原型共享。下面分别对原型和原型链进行简要的解释:

原型(Prototype):

在JavaScript中,每个对象都有一个原型对象(prototype),它是一个指向另一个对象的引用。当访问对象的属性或方法时,如果对象本身没有定义该属性或方法,JavaScript引擎会沿着原型链向上查找,直到找到相应的属性或方法为止。这种机制使得对象可以共享原型对象中的属性和方法,从而实现了对象之间的继承关系。

例如,当我们创建一个新对象时,可以通过Object.create()方法指定原型对象,从而实现对象之间的原型继承。例如:

// 创建一个原型对象
var animal = {
  sound: 'Animal sound',
  makeSound: function() {
    console.log(this.sound);
  }
};

// 创建一个继承自原型对象的新对象
var cat = Object.create(animal);
cat.sound = 'Meow';
cat.makeSound(); // 输出:Meow

在这个例子中,cat对象继承了animal对象的makeSound()方法,当调用cat.makeSound()时,会输出Meow

原型链(Prototype Chain):

原型链是指由对象的原型对象所构成的链式结构,用于描述对象之间的继承关系。当访问对象的属性或方法时,JavaScript引擎会沿着原型链向上查找,直到找到相应的属性或方法为止。如果在整个原型链上都没有找到对应的属性或方法,则返回undefined

例如,假设我们有一个对象obj,它的原型是objProto,而objProto的原型又是objProtoProto,以此类推,形成了一条由原型对象构成的链式结构,即原型链。当访问obj的属性或方法时,JavaScript引擎会沿着这条原型链向上查找,直到找到相应的属性或方法为止,或者返回undefined

// 创建原型链
var objProtoProto = { a: 1 };
var objProto = Object.create(objProtoProto);
var obj = Object.create(objProto);

// 访问属性
console.log(obj.a); // 输出:1

在这个例子中,obj对象继承了objProto对象的a属性,而objProto对象又继承了objProtoProto对象的a属性。当访问obj.a时,JavaScript引擎会沿着原型链向上查找,最终找到了值为1的属性。

11. CDN 加速的概念与原理

CDN(Content Delivery Network,内容分发网络)是一种分布式服务器系统,旨在通过将内容发布到位于世界各地的多个数据中心,从而在全球范围内加速网站内容的传输和分发。其主要原理包括以下几点:

  1. 内容缓存与就近访问: CDN在全球各地建立了大量的服务器节点,这些节点会缓存原始服务器上的内容(如静态文件、图片、视频等),并根据用户的地理位置和网络状况,将内容分发到距离用户最近的节点上。这样,用户在访问网站时可以直接从最近的节点获取内容,大大缩短了内容传输的时间和距离,提高了访问速度和用户体验。

  2. 负载均衡与智能路由: CDN节点之间会根据负载情况和网络状态进行智能路由和负载均衡,确保用户的请求能够快速地被响应,并且有效地利用各个节点的资源。

  3. 内容压缩与优化: CDN可以对内容进行压缩和优化,如压缩图片、合并和压缩CSS和JavaScript文件等,从而减少内容的传输时间和带宽消耗,提高页面加载速度。

  4. 边缘计算与动态缓存: 一些高级CDN服务还提供边缘计算和动态缓存功能,即在CDN节点上执行部分动态内容生成和处理,减轻了原始服务器的负载,并且可以根据用户的需求和环境动态生成和缓存内容。

  5. 安全防护与防御性措施: CDN提供了一些安全防护和防御性措施,如DDoS攻击防护、防止恶意攻击、HTTPS加密传输等,保护网站和用户的安全。

总的来说,CDN通过在全球范围内部署分布式服务器节点,并结合智能路由、内容缓存、负载均衡等技术,加速了网站内容的传输和分发,提高了用户的访问速度和体验,同时减轻了原始服务器的负载,增强了网站的稳定性和安全性。

13. 对闭包的理解

闭包(Closure)是指在函数内部定义的函数可以访问并持有外部函数作用域中的变量,即使外部函数已经执行完毕。换句话说,闭包是一个函数和其相关的引用环境的组合。

要理解闭包,首先需要理解 JavaScript 的词法作用域(Lexical Scope)和函数作用域(Function Scope):

  1. 词法作用域:JavaScript 使用词法作用域,也就是静态作用域,函数的作用域在函数定义的时候就已经确定了,而不是在函数调用的时候确定。

  2. 函数作用域:在 JavaScript 中,每个函数都有自己的作用域,即在函数内部声明的变量只能在函数内部访问,外部无法访问。

闭包的产生是由于 JavaScript 的词法作用域和函数作用域的特性。当一个函数内部定义了另一个函数,并且内部函数引用了外部函数的变量时,就形成了闭包。这个内部函数可以访问外部函数作用域中的变量,即使外部函数执行完毕,这些变量也不会被销毁,因为内部函数仍然持有对这些变量的引用。

闭包的应用场景包括但不限于:

  • 封装私有变量和方法
  • 延迟执行(setTimeout、setInterval)
  • 实现函数柯里化(Currying)和高阶函数
  • 在异步编程中,解决回调函数中无法访问外部作用域的问题

需要注意的是,闭包可能会导致内存泄漏的问题,因为闭包中的变量引用了外部函数的作用域,如果不正确地使用闭包,可能会导致外部函数作用域中的变量无法被释放,从而占用了额外的内存。因此,在使用闭包时,需要注意及时释放不再需要的引用。

15. JavaScript 与 TypeScript 的区别

JavaScript 和 TypeScript 是两种不同的编程语言,它们之间有以下主要区别:

  1. 类型系统

    • JavaScript 是一种动态类型的脚本语言,变量的类型是在运行时确定的,可以随时改变。
    • TypeScript 是 JavaScript 的超集,它添加了静态类型系统,并且可以在编译时进行类型检查。开发者可以为变量、函数参数和返回值等明确地指定类型,这有助于在编码阶段捕获一些潜在的类型错误,提高代码的可靠性和可维护性。
  2. 编译

    • JavaScript 代码可以直接在浏览器中运行,不需要额外的编译步骤。
    • TypeScript 代码需要经过编译成 JavaScript 才能在浏览器中运行。TypeScript 编译器将 TypeScript 代码转换为标准的 JavaScript 代码,这样可以在不同的 JavaScript 运行环境中使用。
  3. 语法扩展

    • TypeScript 在 JavaScript 的基础上扩展了一些语法和功能,例如接口、泛型、枚举、类、命名空间等,这些是 JavaScript 中没有的特性,能够帮助开发者更加高效地进行开发和维护。
  4. 生态系统

    • JavaScript 是一门非常成熟和广泛应用的语言,拥有庞大的生态系统和丰富的资源,包括各种库、框架和工具。
    • TypeScript 相对较新,但其在社区中的影响力越来越大。越来越多的开发者开始使用 TypeScript 来编写前端和后端代码,并且许多流行的库和框架也提供了 TypeScript 的支持。

总的来说,JavaScript 是一门灵活的动态类型语言,适用于各种规模的项目开发,而 TypeScript 则是在 JavaScript 基础上增加了静态类型检查等功能,可以帮助开发者编写更加可靠和可维护的代码。选择使用哪种语言取决于项目的具体需求和开发团队的偏好。

作者:zbwer
链接:www.nowcoder.com/discuss/595…
来源:牛客网