如何让pAequorFactory生成的对象拥有唯一specimenNum?
实现specimenNum唯一性的方案及代码修复
一、核心思路:闭包维护唯一编号
利用闭包保存一个自增计数器或已使用编号集合,让工厂函数自动分配唯一的specimenNum,无需手动传入;若需支持手动指定编号,额外添加重复校验逻辑即可。
二、原代码的错误修复
原代码存在多处语法与逻辑问题,需先修正:
Math.floor[Math.random * 15]改为Math.floor(Math.random() * this.dna.length)(函数调用用(),且适配任意DNA长度)- 未声明的全局变量全部改为局部变量(
randomBaseIndex、mutatedBase、i等) - 赋值错误:
this.dna[randomBaseIndex] === mutatedBase改为this.dna[randomBaseIndex] = mutatedBase - 递归调用
mutate()改为this.mutate(),否则无法访问对象方法 compareDNA和willLikelySurvive中,计数变量需放在循环外,避免每次循环重置
三、完整修正后的代码
// 假设returnRandBase是已定义的随机碱基生成函数 const returnRandBase = () => { const bases = ['A', 'T', 'C', 'G']; return bases[Math.floor(Math.random() * 4)]; }; // 闭包维护唯一标本编号 const pAequorFactory = (() => { let specimenCounter = 1; return (dna) => { const specimenNum = specimenCounter++; return { specimenNum, dna: [...dna], // 浅拷贝避免外部修改影响内部DNA mutate() { const randomBaseIndex = Math.floor(Math.random() * this.dna.length); let mutatedBase = returnRandBase(); // 确保突变碱基与原碱基不同 while (this.dna[randomBaseIndex] === mutatedBase) { mutatedBase = returnRandBase(); } this.dna[randomBaseIndex] = mutatedBase; return this.dna; }, compareDNA(other) { let commonCount = 0; const dnaLength = Math.min(this.dna.length, other.dna.length); for (let i = 0; i < dnaLength; i++) { if (this.dna[i] === other.dna[i]) { commonCount++; } } const commonPercentage = ((commonCount / dnaLength) * 100).toFixed(2); return `specimen #${this.specimenNum} and specimen #${other.specimenNum} have ${commonPercentage}% DNA in common`; }, willLikelySurvive() { let cgCount = 0; for (let base of this.dna) { if (base === 'C' || base === 'G') { cgCount++; } } const survivePercentage = (cgCount / this.dna.length) * 100; return survivePercentage >= 60; }, }; }; })(); // 使用示例 const dnaSample = Array.from({length:15}, returnRandBase); const pAequor1 = pAequorFactory(dnaSample); const pAequor2 = pAequorFactory(dnaSample); console.log(pAequor1.specimenNum); // 输出1 console.log(pAequor2.specimenNum); // 输出2
四、支持手动传入编号的扩展方案
如果必须允许手动指定specimenNum,可在闭包中维护已使用编号集合,添加重复校验:
const pAequorFactory = (() => { const usedNumbers = new Set(); let autoCounter = 1; return (specimenNum, dna) => { let finalNum; // 处理手动传入编号的情况 if (specimenNum !== undefined) { if (usedNumbers.has(specimenNum)) { throw new Error(`Specimen number ${specimenNum} is already in use`); } finalNum = specimenNum; } else { // 自动分配未使用的编号 while (usedNumbers.has(autoCounter)) { autoCounter++; } finalNum = autoCounter++; } usedNumbers.add(finalNum); return { specimenNum: finalNum, dna: [...dna], // 其余方法同上述修正版本 }; }; })();
内容的提问来源于stack exchange,提问作者huz3y
相关产品推荐
相关产品推荐

