JavaScript替换男性代词为女性代词的更优实现方案咨询
优化名言生成器的性别表述替换逻辑
问题背景
开发了一个JavaScript名言生成器,需要实现将名言中的男性表述替换为女性表述的功能,数据源是包含1500条名言对象的数组。现有实现可正常运行,但代码冗余度高,不符合DRY原则,需要更简洁的解决方案。
原实现代码
//Show new quote function newQuote() { loading(); //Pick a random from apiQuotes array const quote = apiQuotes[Math.floor(Math.random() * apiQuotes.length)]; //Searching for male terms and making them female //turn quote.text into an array this will make it easier to match the male terms and make them //because if we tried to do .replace or .replaceAll it would replace parts of substrings as well let quoteArray = quote.text.split(" "); // now we are making a if statement to turn these generic terms into women specific terms let newArrayQuote = quoteArray.map((index) => { if (index === "he") { return "she"; } if (index === "he.") { return "she."; } if (index === "He") { return "She"; } if (index === "his") { return "hers"; } if (index === "His") { return "Hers"; } if (index === "him") { return "her"; } if (index === "him.") { return "her."; } if (index === "Him") { return "Her"; } if (index === "men") { return "women"; } if (index === "men,") { return "women,"; } if (index === "Men") { return "Women"; } if (index === "man") { return "woman"; } if (index === "man.") { return "woman."; } if (index === "Man") { return "Woman"; } if (index === "himself") { return "herself"; } if (index === "himself.") { return "herself."; } else { return index; } }); //turning the newArrayQuote back into string let stringQuote = newArrayQuote.join(" "); //Check if Author field is blank and replace it with unknown if (!quote.author) { authorText.textContent = "Unknown"; } else { authorText.textContent = quote.author; } // Check quote length to determine the styling if (stringQuote.length > 120) { quoteText.classList.add("long-quote"); } else { quoteText.classList.remove("long-quote"); } //Set Quote, Hide Loader complete(); quoteText.textContent = stringQuote; }
优化方案
核心思路
- 映射表集中管理替换规则:把所有需要替换的男性表述与对应女性表述存入对象,彻底消除重复的
if判断。 - 正则处理单词与标点:通过正则匹配完整单词(借助
\b确保不替换子字符串),同时提取末尾标点,替换后自动拼接,无需单独处理带标点的单词。 - 抽离独立工具函数:将性别替换逻辑封装成单独函数,提升代码可读性与复用性。
优化后代码
// 性别表述映射表:新增/修改规则只需在此调整 const genderReplaceMap = { 'he': 'she', 'He': 'She', 'his': 'hers', 'His': 'Hers', 'him': 'her', 'Him': 'Her', 'men': 'women', 'Men': 'Women', 'man': 'woman', 'Man': 'Woman', 'himself': 'herself', 'Himself': 'Herself' }; // 替换性别表述的工具函数 function replaceGenderTerms(text) { // 构建正则:匹配映射表中的所有单词,捕获末尾标点 const replaceRegex = new RegExp(`\\b(${Object.keys(genderReplaceMap).join('|')})([.,!?]*)\\b`, 'g'); return text.replace(replaceRegex, (_, targetWord, punctuation) => { return genderReplaceMap[targetWord] + punctuation; }); } //Show new quote function newQuote() { loading(); //Pick a random from apiQuotes array const quote = apiQuotes[Math.floor(Math.random() * apiQuotes.length)]; // 直接调用工具函数完成替换 const stringQuote = replaceGenderTerms(quote.text); // 简化作者为空的判断逻辑 authorText.textContent = quote.author || "Unknown"; // 用toggle简化类名操作 quoteText.classList.toggle("long-quote", stringQuote.length > 120); //Set Quote, Hide Loader complete(); quoteText.textContent = stringQuote; }
额外优化细节
- 用
quote.author || "Unknown"替代冗余的if-else判断。 - 用
classList.toggle的第二个参数,实现条件添加/移除类名的简洁写法。
内容的提问来源于stack exchange,提问作者keller
相关产品推荐
相关产品推荐

