• 前端面试题09


    74、定义类的方法有哪些

    在JavaScript中,定义类的方法有以下几种方式:

    1.使用函数声明:

    function MyClass() {
      // constructor
    }
    MyClass.prototype.methodName = function() {
      // method body
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.使用类的方法缩写(ES6引入):

    class MyClass {
      methodName() {
        // method body
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3.使用对象字面量赋值:

    const MyClass = {
      methodName: function() {
        // method body
      }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5

    4.使用ES6箭头函数

    class MyClass {
      methodName = () => {
        // method body
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    无论使用哪种方式,类的方法都可以在类的实例对象上被调用。使用this关键字可以在方法中引用当前实例的属性和方法。 这些方法定义方式的选择取决于代码结构和个人偏好。在ES6中,推荐使用类的方法缩写方式,因为它更简洁和清晰,支持更多的语法特性。

    75、Object.is()和==、===之间的区别

    Object.is(value1, value2):

    • Object.is() 是一个静态方法,用于判断两个值是否严格相等。

    • 它的比较行为与 === 运算符一致,只有在两个值严格相等时返回 true,否则返回 false

    • === 运算符不同的是,Object.is() 对于 NaN 和 -0 有特殊处理,将它们视为不相等。

    • 示例:

      Object.is(3, 3);      // true
      Object.is('foo', 'foo');    // true
      Object.is(true, true);      // true
      Object.is(undefined, undefined);  // true
      Object.is(null, undefined);     // false
      Object.is(0, -0);       // false
      Object.is(NaN, NaN);      // false
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

    == 运算符(相等运算符):

    • == 运算符用于将两个操作数进行比较,如果它们的值相等,返回 true,否则返回 false

    • 在进行比较之前,会进行类型转换,使得两个操作数具有相同的类型。

    • 进行比较时,会遵循一些特定的规则(类型转换规则)。

    • 例子:

      1 == 1;          // true
      '1' == 1;        // true
      0 == false;      // true
      null == undefined;  // true
      NaN == NaN;      // false
      
      • 1
      • 2
      • 3
      • 4
      • 5

    === 运算符(严格相等运算符):

    • === 运算符用于比较两个操作数的值和类型是否完全相等,若完全相等,则返回 true,否则返回 false

    • 不进行类型转换。

    • 示例:

      1 === 1;                // true
      '1' === 1;              // false
      0 === false;            // false
      null === undefined;     // false
      0 === -0;				// true
      NaN === NaN;            // false
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

    综上所述,Object.is() 是严格相等运算符的一种更严格的版本,主要区别在于对 0 和 -0 值的处理方式。而 == 运算符则会进行类型转换,再进行比较。最好的实践是在大多数情况下使用 === 运算符进行值的比较,只在需要考虑特殊情况时使用 Object.is()

    76、Vue中虚拟DOM的作用

    1. 提高渲染效率:虚拟DOM可以通过diff算法来比较前后两个虚拟DOM树的差异,只对差异部分进行实际的DOM更新操作,避免对整个DOM树进行重新渲染,从而提高了页面的渲染效率。
    2. 简化开发:虚拟DOM将真实DOM的操作抽象成跨平台、可复用的JavaScript对象,使得开发者可以使用组件化的方式来构建应用,将UI拆分为多个可组合的组件,简化了应用的开发和维护。
    3. 跨平台支持:由于虚拟DOM是基于JavaScript对象的抽象结构,它可以支持跨不同平台的开发,比如在浏览器、桌面应用和移动端应用等平台上使用相同的组件和代码逻辑进行开发。
    4. 高效的跟踪和更新:Vue的响应式系统结合虚拟DOM可以实现高效的状态追踪和更新。当应用的状态发生变化时,Vue会通过虚拟DOM的diff算法计算出需要更新的最小DOM操作,只对需要更新的部分进行实际的DOM更新,从而提高了应用的性能。

    虚拟DOM技术使得Vue可以在保持开发效率和性能之间取得平衡,提供了一个高效、组件化的方式来构建交互式的前端应用。它在Vue中扮演了关键的角色,使得开发者可以更好地管理和控制应用的状态和渲染过程。

    77、CSS过渡属性和动画的区别

    1. 触发方式:过渡属性是响应状态改变的,只有当某个属性的值发生变化时,过渡效果才会触发。而动画是无需响应状态的改变,可以通过添加类名或使用JavaScript来触发动画效果。
    2. 使用场景:过渡属性适用于简单的状态改变,如鼠标悬停、元素出现/消失等,常用于实现一些平滑的过渡效果。动画则适用于更复杂、更精细的动画效果,可以实现更高级的交互和动态效果。
    3. 配置灵活性:动画相对于过渡属性在配置灵活性上更强大。使用关键帧(Keyframes)规则,可以在动画序列中定义多个阶段,并设置每个阶段所需的样式属性。这使得动画可以实现更复杂的变化和多样化的效果。
    4. 控制和自定义:过渡属性的控制比较简单,主要通过定义过渡属性和过渡的时间曲线来控制过渡的效果。而动画可以通过JavaScript控制动画的播放、暂停、重复等行为,并通过CSS提供的其他属性(如animation-fill-mode、animation-iteration-count等)进行自定义。

    总结来说,过渡属性适用于简单的状态改变,并且控制和配置相对简单,可以实现平滑的过渡效果。而动画更适用于复杂的、精细的动态效果,可以通过关键帧规则和JavaScript控制,实现更丰富多样的动画效果。在实际开发中,可以根据需求来选择使用过渡属性还是动画来实现相应的动画效果。

    78、让一段JavaScript代码异步执行

    1、使用setTimeout函数:setTimeout函数可以在指定的时间间隔后异步执行指定的代码。你可以将你想要异步执行的代码包装在一个回调函数内,然后使用setTimeout来设置一个延迟的时间。

    setTimeout(function() {
      // 在这里编写你想要异步执行的代码
    }, 0);
    
    • 1
    • 2
    • 3

    使用setTimeout的这种方式可以立即将代码放入事件循环队列中,以便在其他同步代码执行完成后被执行。

    2、使用Promise对象:Promise对象提供了一种更优雅的方式来处理异步操作。你可以创建一个Promise对象并在其中定义异步操作的逻辑。在异步操作完成后,调用resolve函数来标志操作成功并传递结果,或调用reject函数来标志操作失败并传递错误信息。

    new Promise(function(resolve, reject) {
      // 异步操作的逻辑
      // 在操作成功后,调用 resolve(value)
      // 在操作失败后,调用 reject(error)
    }).then(function(result) {
      // 在操作成功后的处理逻辑
    }).catch(function(error) {
      // 在操作失败后的处理逻辑
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    你可以在Promise对象的then方法中处理成功的逻辑,在catch方法中处理失败的逻辑。

    3、使用async/awaitasync/await是一种更简洁的处理异步操作的方法,它基于Promise对象。你可以将要执行的异步代码放在一个async函数中,然后使用await关键字来等待异步操作的完成。

    async function asyncFunction() {
      await asyncOperation();  // 异步操作
      // 执行其他的代码
    }
    
    • 1
    • 2
    • 3
    • 4

    在使用await关键字时,它会暂停async函数的执行,直到异步操作完成并返回结果,然后继续执行之后的代码。

    79、单页应用程序首屏优化有哪些方法

    1. 按需加载:将页面资源(如 JavaScript、CSS、图片等)进行按需加载,而不是一次性加载所有资源。可以使用异步加载、懒加载等技术,并优化资源的加载顺序,保证先加载必要的资源,再加载其他次要的资源。
    2. 代码分割:将应用程序的代码拆分成多个模块,按需加载模块,可以使用工具如Webpack等进行代码分割。这样可以减少首屏需要加载的代码量,提高页面渲染速度。
    3. 图片优化:使用适当的图片格式、压缩图片大小,减少网络传输的数据量。可以使用工具如ImageOptim、TinyPNG等进行图片优化,同时,可以使用懒加载技术(如LazyLoad)延迟加载图片,减少首屏需要加载的图片数量。
    4. 预渲染:对于一些静态内容不经常变化的页面,可以使用预渲染技术,在服务器端生成好首屏内容,并将其作为静态HTML文件返回给客户端,从而加快页面加载速度。
    5. 缓存策略:合理利用浏览器缓存和服务器缓存,将可能重复请求的资源缓存起来,减少请求次数和网络传输时间。可以使用HTTP缓存头,如Cache-Control、Expires等,设置合理的缓存时间。
    6. 代码优化:减少不必要的重绘和重排,避免过多的DOM操作,优化JavaScript代码,减少CPU计算时间。使用工具如Chrome DevTools进行性能分析,找出性能瓶颈并进行优化。
    7. 服务器优化:确保服务器的响应速度快,减少网络延迟。可以使用CDN(内容分发网络)来加速静态资源的加载,将资源分布到离用户更近的服务器上。
    8. 骨架屏:在页面加载过程中,可以使用骨架屏技术展示一个简单的页面结构,提供视觉反馈,让用户感知到页面正在加载,从而减少等待时间的焦虑感。

    80、Vue中如何实现单页应用程序的页面缓存

    1、使用组件:Vue提供了一个名为keep-alive的特殊组件,可用于缓存动态组件的状态。

    <router-view v-slot="{ Component }">
      <keep-alive>
        <component :is="Component">component>
      keep-alive>
    router-view>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    通过将组件包裹在周围,你可以缓存通过Vue Router渲染的组件。这样,当你在不同的页面切换时,组件的状态将被保留,而不会重新加载。

    2、使用$route.meta属性:在路由配置中,可以为每个路由定义一个meta对象,用于存储一些自定义数据。你可以利用该属性来判断是否需要缓存页面。

    const router = new VueRouter({
      routes: [
        {
          path: '/home',
          component: Home,
          meta: { 
            keepAlive: true // 需要缓存
          }
        },
        {
          path: '/about',
          component: About,
          meta: { 
            keepAlive: false // 不需要缓存
          }
        }
      ]
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    然后,你可以在页面组件中通过$route.meta.keepAlive属性来决定是否缓存该页面。

    3、使用activated和deactivated生命周期钩子:如果某个页面经常需要刷新或者不适合使用组件,你可以使用组件的activated和deactivated生命周期钩子来手动处理页面的缓存。

    export default {
      activated() {
        // 页面被激活时触发
        // 在这里可以加载数据或执行其他操作
      },
      deactivated() {
        // 页面失去激活状态时触发
        // 在这里可以清除数据或执行其他操作
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    当页面切换时,activated和deactivated钩子会被依次触发,你可以在这里处理缓存逻辑。

  • 相关阅读:
    605. 简单乘积
    蓝桥杯(杂题1)
    静态代码块和构造代码块
    Spring Security 集成 OAuth 2.0 认证(一)
    20221204今天的世界发生了什么
    Python数据分析案例12——网飞影视剧数据分析及其可视化
    电梯物联网之梯控相机方案-防止电瓶车进电梯
    Python 基础记录 - 第1课
    水稻育种技术全球领先海外市场巨大 国稻种芯百团计划行动
    人工智能的发展前景如何
  • 原文地址:https://blog.csdn.net/weixin_57837275/article/details/134753132