You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化图片尺寸计算函数中的大量if-else逻辑?

优化图片尺寸计算函数的思路

问题背景

我有一个接收初始width、height、比例ratio和用户设备device的函数getSize,用户可将图片宽高定义为%、px或'auto'字符串,需要覆盖所有可能场景,但当前代码嵌套复杂、臃肿,希望摆脱if-else嵌套,实现代码动态化与优化。

原代码如下:

const getSize = (width, height, ratio, device) => {
    const myWidth =
        device === 'Mobile'
            ? item.media?.mobile?.style?.width
            : device === 'Tablet'
            ? item.media?.tablet?.style?.width
            : item.style?.width;
    const myHeight =
        device === 'Mobile'
            ? item.media?.mobile?.style?.height
            : device === 'Tablet'
            ? item.media?.tablet?.style?.height
            : item.style?.height;

    const widthCondition = !myWidth || myWidth === 'auto';
    const heightCondition = !myHeight || myHeight === 'auto';

    if (widthCondition) {
        setNewWidth(width);
        const pixelHeight = findHeightOrWidth(width, ratio);
        setNewHeight(pixelHeight);
        return;
    }

    if (myWidth.includes('%')) {
        const percentage = parseInt(myWidth, 10);
        const calculatedWidth = getPercentValue(width, percentage);
        setNewWidth(calculatedWidth);

        if (heightCondition) {
            const calculatedHeight = getPercentValue(height, percentage);
            setNewHeight(calculatedHeight);
        }
        return;
    }

    if (myWidth.includes('px')) {
        setNewWidth(parseInt(myWidth, 10));
        if (heightCondition) {
            const pixelWidth = parseInt(myWidth, 10);
            const pixelHeight = findHeightOrWidth(pixelWidth, ratio);
            setNewHeight(pixelHeight);
        } else {
            setNewHeight(parseInt(myHeight, 10));
        }
        return;
    }

    if (myHeight?.includes('%')) {
        const percentage = parseInt(myHeight, 10);
        const calculatedHeight = getPercentValue(height, percentage);
        setNewHeight(calculatedHeight);
        if (widthCondition) {
            const calculatedWidth = getPercentValue(height, percentage);
            setNewWidth(calculatedWidth);
        }
        return;
    }

    if (myHeight?.includes('px')) {
        setNewHeight(parseInt(myHeight, 10));
        if (widthCondition) {
            const pixelHeight = parseInt(myHeight, 10);
            const pixelWidth = findHeightOrWidth(pixelHeight, ratio);
            setNewWidth(pixelWidth);
        } else {
            setNewWidth(parseInt(myWidth, 10));
        }
    }
};

优化思路

1. 统一设备样式获取逻辑

用对象映射替代嵌套三元表达式,直接根据设备类型匹配对应的样式对象,代码更直观易维护:

const deviceStyleMap = {
  Mobile: item.media?.mobile?.style,
  Tablet: item.media?.tablet?.style,
  default: item.style
};
const targetStyle = deviceStyleMap[device] || deviceStyleMap.default;
const myWidth = targetStyle?.width;
const myHeight = targetStyle?.height;

2. 提取尺寸解析工具函数

把宽高字符串的解析逻辑抽成独立函数,一次性识别尺寸类型(px/%/auto)和对应数值,避免重复编写includes和parseInt逻辑:

const parseSize = (sizeStr) => {
  if (!sizeStr || sizeStr === 'auto') {
    return { type: 'auto', value: null };
  }
  if (sizeStr.includes('%')) {
    return { type: '%', value: parseInt(sizeStr, 10) };
  }
  if (sizeStr.includes('px')) {
    return { type: 'px', value: parseInt(sizeStr, 10) };
  }
  // 处理无效值,默认按auto处理
  return { type: 'auto', value: null };
};

// 使用示例
const widthInfo = parseSize(myWidth);
const heightInfo = parseSize(myHeight);

3. 用策略模式处理尺寸组合场景

针对宽高类型的所有组合(比如auto-auto、%-px等),定义对应的处理策略函数,通过类型组合的key匹配执行,彻底消除if-else嵌套:

// 定义所有尺寸组合的处理策略
const sizeStrategies = {
  'auto-auto': () => {
    setNewWidth(width);
    setNewHeight(findHeightOrWidth(width, ratio));
  },
  '%-auto': () => {
    const calculatedWidth = getPercentValue(width, widthInfo.value);
    setNewWidth(calculatedWidth);
    setNewHeight(getPercentValue(height, widthInfo.value));
  },
  'px-auto': () => {
    setNewWidth(widthInfo.value);
    setNewHeight(findHeightOrWidth(widthInfo.value, ratio));
  },
  'auto-%': () => {
    const calculatedHeight = getPercentValue(height, heightInfo.value);
    setNewHeight(calculatedHeight);
    setNewWidth(getPercentValue(width, heightInfo.value));
  },
  'auto-px': () => {
    setNewHeight(heightInfo.value);
    setNewWidth(findHeightOrWidth(heightInfo.value, ratio));
  },
  'px-px': () => {
    setNewWidth(widthInfo.value);
    setNewHeight(heightInfo.value);
  },
  '%-%': () => {
    setNewWidth(getPercentValue(width, widthInfo.value));
    setNewHeight(getPercentValue(height, heightInfo.value));
  },
  '%-px': () => {
    setNewWidth(getPercentValue(width, widthInfo.value));
    setNewHeight(heightInfo.value);
  },
  'px-%': () => {
    setNewWidth(widthInfo.value);
    setNewHeight(getPercentValue(height, heightInfo.value));
  }
};

// 执行对应策略
const strategyKey = `${widthInfo.type}-${heightInfo.type}`;
sizeStrategies[strategyKey]?.();

4. 整合优化后的完整代码

const parseSize = (sizeStr) => {
  if (!sizeStr || sizeStr === 'auto') {
    return { type: 'auto', value: null };
  }
  if (sizeStr.includes('%')) {
    return { type: '%', value: parseInt(sizeStr, 10) };
  }
  if (sizeStr.includes('px')) {
    return { type: 'px', value: parseInt(sizeStr, 10) };
  }
  return { type: 'auto', value: null };
};

const getSize = (width, height, ratio, device) => {
  // 统一设备样式获取
  const deviceStyleMap = {
    Mobile: item.media?.mobile?.style,
    Tablet: item.media?.tablet?.style,
    default: item.style
  };
  const targetStyle = deviceStyleMap[device] || deviceStyleMap.default;
  const myWidth = targetStyle?.width;
  const myHeight = targetStyle?.height;

  // 解析宽高类型与数值
  const widthInfo = parseSize(myWidth);
  const heightInfo = parseSize(myHeight);

  // 定义尺寸处理策略
  const sizeStrategies = {
    'auto-auto': () => {
      setNewWidth(width);
      setNewHeight(findHeightOrWidth(width, ratio));
    },
    '%-auto': () => {
      const calculatedWidth = getPercentValue(width, widthInfo.value);
      setNewWidth(calculatedWidth);
      setNewHeight(getPercentValue(height, widthInfo.value));
    },
    'px-auto': () => {
      setNewWidth(widthInfo.value);
      setNewHeight(findHeightOrWidth(widthInfo.value, ratio));
    },
    'auto-%': () => {
      const calculatedHeight = getPercentValue(height, heightInfo.value);
      setNewHeight(calculatedHeight);
      setNewWidth(getPercentValue(width, heightInfo.value));
    },
    'auto-px': () => {
      setNewHeight(heightInfo.value);
      setNewWidth(findHeightOrWidth(heightInfo.value, ratio));
    },
    'px-px': () => {
      setNewWidth(widthInfo.value);
      setNewHeight(heightInfo.value);
    },
    '%-%': () => {
      setNewWidth(getPercentValue(width, widthInfo.value));
      setNewHeight(getPercentValue(height, heightInfo.value));
    },
    '%-px': () => {
      setNewWidth(getPercentValue(width, widthInfo.value));
      setNewHeight(heightInfo.value);
    },
    'px-%': () => {
      setNewWidth(widthInfo.value);
      setNewHeight(getPercentValue(height, heightInfo.value));
    }
  };

  // 执行对应策略
  sizeStrategies[`${widthInfo.type}-${heightInfo.type}`]?.();
};

内容的提问来源于stack exchange,提问作者Promise Ghosh Chowdhury

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 18:15:36