MST

星途 面试题库

面试题:JavaScript为已有类添加方法时的性能优化考量

给定一个频繁实例化的类`Widget`,代码如下:`function Widget(id) { this.id = id; }`。现在要为`Widget`类添加一个`update`方法,该方法执行复杂的DOM操作。请从性能角度出发,设计一个优化的代码方案,并解释为何这种方案能提升性能,同时说明如何避免内存泄漏问题。
12.8万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试
  1. 优化代码方案
    • 使用原型链来添加update方法。
    function Widget(id) {
        this.id = id;
    }
    Widget.prototype.update = function() {
        // 这里写复杂的DOM操作代码
        console.log('执行复杂DOM操作,针对id为'+ this.id +'的Widget');
    };
    
  2. 性能提升原因
    • 当使用原型链添加方法时,所有Widget实例共享这一个update方法。如果直接在构造函数内部定义方法,每次实例化Widget时都会创建一个新的函数实例,这会消耗更多的内存。而共享原型上的方法,多个实例可以复用这一个方法,减少了内存占用,从而提升性能,特别是在频繁实例化Widget类的情况下。
  3. 避免内存泄漏问题
    • update方法中处理DOM操作时
      • 确保在移除DOM元素时,解除所有相关的事件绑定。例如,如果在update方法中为某个DOM元素添加了事件监听器,在移除该DOM元素前,要使用element.removeEventListener('eventType', callback)方法移除事件监听器。
      • 避免循环引用。如果在update方法中创建了对象之间的相互引用,确保在不再需要这些对象时,手动解除引用。例如,如果一个DOM元素引用了Widget实例,而Widget实例又引用了该DOM元素,在销毁Widget实例或移除DOM元素时,要切断这些引用。
    • Widget实例销毁时
      • 如果Widget实例有一些定时器(setTimeoutsetInterval),在实例销毁前要清除这些定时器。例如,在Widget类中添加一个destroy方法:
      Widget.prototype.destroy = function() {
          if (this.timer) {
              clearTimeout(this.timer);
              this.timer = null;
          }
          // 这里还可以添加其他清理操作,如移除事件监听器等
      };
      
      这样在不再需要Widget实例时,调用widgetInstance.destroy()方法,可以避免因定时器未清除等原因导致的内存泄漏。