在JavaScript中创建一个单位转换器数据结构
基于类的单位转换器数据结构
在最简单的形式中,任何基于单位的值都是一个带有附加单位的数值。只要单位是兼容的并且你知道它们之间的转换因子,就可以很容易地从一个单位转换到另一个单位。
应用这个逻辑,我们可以为距离单位创建一个简单的数据结构类。该数据结构将在内部将值存储为厘米,并提供从其他单位转换的方法。
为了避免手动添加每个转换,我们可以使用Object.defineProperty()
轻松地为每个单位创建一个getter,它将计算指定单位的值。类似地,我们还可以为每个单位创建一个静态方法,该方法将创建一个新的数据结构实例,并将值转换为内部存储的单位。
class Distance {
static conversions = {
inches: 2.54,
feet: 30.48,
yards: 91.44,
miles: 160934.4,
centimeters: 1,
meters: 100,
kilometers: 100000,
};
constructor(cm) {
this.cm = cm;
}
}
Object.entries(Distance.conversions).forEach(([unit, conversion]) => {
Object.defineProperty(
Distance,
`from${unit.charAt(0).toUpperCase() + unit.slice(1)}`,
{
get: function () {
return value => new Distance(value * conversion);
},
}
);
Object.defineProperty(Distance.prototype, unit, {
get: function () {
return this.cm / conversion;
},
});
});
const distance = Distance.fromMeters(10);
单位转换器数据结构工厂函数
虽然这对于特定类型的测量工作得很好,但我们必须为不同类型的测量重复整个过程。这并不理想,因为我们可能会出现很多代码重复。
幸运的是,JavaScript使用原型继承,这意味着我们可以使用一个函数来代替类,并应用相同类型的逻辑来创建一个通用的单位转换器数据结构。这将允许我们创建一个单一的工厂函数,用于创建任何类型的测量单位转换器。
const createUnitConverter = unitCoversions => {
// 创建一个充当数据结构的函数
const UnitConverter = function (unit) {
this.unit = unit;
};
// 添加静态方法
Object.entries(unitCoversions).forEach(([unit, conversion]) => {
Object.defineProperty(
UnitConverter,
`from${unit.charAt(0).toUpperCase() + unit.slice(1)}`,
{
get: function () {
return value => new UnitConverter(value * conversion);
},
}
);
// 添加实例方法
Object.defineProperty(UnitConverter.prototype, unit, {
get: function () {
return this.unit / conversion;
},
});
});
return UnitConverter;
};
const Data = createUnitConverter({
bits: 1,
bytes: 8,
kilobits: 1000,
kilobytes: 8000,
megabits: 1000000,
megabytes: 8000000,
gigabits: 1000000000,
gigabytes: 8000000000,
terabits: 1000000000000,
terabytes: 8000000000000,
petabits: 1000000000000000,
petabytes: 8000000000000000,
});
const data = Data.fromBytes(2000);
```javascript
data.kilobytes; // 2
data.bits; // 16000
虽然这对于简单的公式有效,但像温度转换这样的东西就要复杂一些。我不会在这里详细介绍,但我相信你可以很容易地找出必要的调整,以允许使用函数而不是简单的转换因子。