JavaScript封装函数等代码逻辑时,选择类还是Hooks?

291 阅读4分钟

当你要在 JavaScript 里封装函数和属性时,纠结选类还是类似 React Hooks 那种函数式风格,就好比纠结是开房车旅行还是骑单车出游,各有各的妙处,得看你的具体行程(使用场景)啦!

封装目的和复杂度

  • 类:功能齐全的房车
    类就像是一辆功能齐全的房车,适合处理复杂的封装任务。当你需要封装一系列相互关联的属性和方法,并且希望这些属性和方法有明确的归属和访问控制时,类就是你的好选择。它就像房车里有卧室、厨房、卫生间,每个区域都有特定的功能,而且你可以控制谁能进入哪个区域。

比如说,你要封装一个处理图形的功能,有不同的图形(如圆形、矩形),每个图形都有自己的属性(半径、长、宽)和方法(计算面积、周长),用类来封装就非常合适。

class Shape {
    constructor() {
        // 基础属性和初始化操作
    }
}

class Circle extends Shape {
    constructor(radius) {
        super();
        this.radius = radius;
    }

    getArea() {
        return Math.PI * this.radius * this.radius;
    }

    getPerimeter() {
        return 2 * Math.PI * this.radius;
    }
}

class Rectangle extends Shape {
    constructor(length, width) {
        super();
        this.length = length;
        this.width = width;
    }

    getArea() {
        return this.length * this.width;
    }

    getPerimeter() {
        return 2 * (this.length + this.width);
    }
}

const circle = new Circle(5);
console.log(circle.getArea()); 

const rectangle = new Rectangle(4, 6);
console.log(rectangle.getPerimeter()); 
  • 函数式封装(类似 Hooks):灵活的单车
    函数式封装就像一辆灵活的单车,适合处理简单、独立的封装任务。当你只需要封装一个单一的功能,并且这个功能不需要维护复杂的状态时,函数式封装会更简洁高效。它就像骑单车,想去哪儿就去哪儿,没有太多的束缚。

比如,你要封装一个简单的日期格式化函数,用函数式封装就足够了。

function formatDate(date) {
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    return `${year}-${month}-${day}`;
}

const today = new Date();
console.log(formatDate(today)); 

代码复用性

  • 类:家族传承的房车
    类的代码复用就像家族传承的房车,通过继承和多态的方式,可以让子类复用父类的属性和方法,就像后代继承了先辈的房车,还能根据自己的需求进行改装。

例如,你有一个基础的动物类,不同的动物(如猫、狗)可以继承这个类,并扩展自己的行为。

class Animal {
    constructor(name) {
        this.name = name;
    }

    speak() {
        console.log(`${this.name} makes a sound.`);
    }
}

class Cat extends Animal {
    speak() {
        console.log(`${this.name} meows.`);
    }
}

class Dog extends Animal {
    speak() {
        console.log(`${this.name} barks.`);
    }
}

const cat = new Cat('Whiskers');
cat.speak(); 

const dog = new Dog('Buddy');
dog.speak(); 
  • 函数式封装(类似 Hooks):共享的单车
    函数式封装的代码复用就像共享的单车,你可以把一个函数封装好,然后在不同的地方多次使用,就像不同的人可以骑同一辆共享单车去不同的地方。

比如,你封装了一个计算两个数之和的函数,就可以在多个地方复用它。

function add(a, b) {
    return a + b;
}

const result1 = add(2, 3);
const result2 = add(5, 7);
console.log(result1, result2); 

状态管理

  • 类:有管家的房车
    类在处理状态管理时,就像房车里有个管家,你可以通过类的属性来存储和管理状态,并且可以在类的方法中对状态进行操作。管家会帮你记住房车里各种东西的状态,并且按照你的要求进行调整。 例如,你要封装一个计数器类,通过类的属性来记录计数状态。
class Counter {
    constructor() {
        this.count = 0;
    }

    increment() {
        this.count++;
    }

    getCount() {
        return this.count;
    }
}

const counter = new Counter();
counter.increment();
console.log(counter.getCount()); 
  • 函数式封装(类似 Hooks):自己管自己的单车客
    函数式封装在处理状态管理时,通常会使用闭包或者参数来传递状态,就像骑单车的人自己管理自己携带的物品。你可以在函数内部使用变量来存储临时状态,或者通过参数将状态传递给函数。 比如,你可以封装一个函数来实现计数器功能,使用闭包来管理计数状态。
function createCounter() {
    let count = 0;
    return function() {
        count++;
        return count;
    };
}

const counterFunction = createCounter();
console.log(counterFunction()); 

代码可读性和维护性

  • 类:有详细地图的房车旅行
    类的代码结构相对清晰,属性和方法都有明确的定义和归属,就像房车旅行有详细的地图,每个景点和路线都标得清清楚楚。对于熟悉面向对象编程的人来说,类的代码更容易理解和维护。
  • 函数式封装(类似 Hooks):随性的单车之旅
    函数式封装的代码通常比较简洁,逻辑单一,就像随性的单车之旅,没有太多复杂的路线规划,一眼就能看出要做什么。但如果逻辑变得复杂,可能会导致函数过长,影响可读性。

性能考虑

  • 类:房车的油耗
    类在创建实例时会有一定的开销,就像房车启动和行驶时会消耗较多的油耗。如果需要频繁创建类的实例,可能会对性能产生一定的影响。
  • 函数式封装(类似 Hooks):单车的零油耗
    函数式封装通常没有创建实例的开销,就像骑单车零油耗,性能开销相对较小。在处理简单任务时,函数式封装的性能会更好。

所以呀,到底选类还是函数式封装,就看你的封装任务是像一场豪华的房车旅行,还是一次轻松的单车出游啦!