如何优化图片尺寸计算函数中的大量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
相关产品推荐
相关产品推荐

