我用JavaScript制作一个密码生成器,它通过从输入中获得一个数字来工作,它生成一个密码,它从输入中获得的长度。我在HTML中添加了三个复选框,分别表示大写字母、数字和符号。如果您不选中复选框,它将只使用小写字母生成密码,但是如果您标记了大写复选框,它将同时使用小写和大写字母来创建密码,并且与其他复选框的工作方式相同。
为了计算哪些复选框被选中,我必须使用大量的if语句,下面是我的代码:
if (document.getElementById('caps').checked === true &&
document.getElementById('numbers').checked === false &&
document.getElementById('symbols').checked === false)
{
const charsArray = lowercase.concat(caps);
password = GeneratePassword(passwordLength, charsArray);
}
else if (document.getElementById('caps').checked === false &&
document.getElementById('numbers').checked === true &&
document.getElementById('symbols').checked === false)
{
const charsArray = lowercase.concat(numbers);
password = GeneratePassword(passwordLength, charsArray);
}
else if (document.getElementById('caps').checked === false &&
document.getElementById('numbers').checked === false &&
document.getElementById('symbols').checked === true)
{
const charsArray = lowercase.concat(symbols);
password = GeneratePassword(passwordLength, charsArray);
}
else if (document.getElementById('caps').checked === true &&
document.getElementById('numbers').checked === true &&
document.getElementById('symbols').checked === false)
{
const charsArray = lowercase.concat(caps).concat(numbers);
password = GeneratePassword(passwordLength, charsArray);
}
else if (document.getElementById('caps').checked === true &&
document.getElementById('numbers').checked === true &&
document.getElementById('symbols').checked === true)
{
const charsArray = lowercase.concat(caps).concat(numbers).concat(symbols);
password = GeneratePassword(passwordLength, charsArray);
}
else if (document.getElementById('caps').checked === false &&
document.getElementById('numbers').checked === true &&
document.getElementById('symbols').checked === true)
{
const charsArray = lowercase.concat(numbers).concat(symbols);
password = GeneratePassword(passwordLength, charsArray);
}
else if (document.getElementById('caps').checked === true &&
document.getElementById('numbers').checked === false &&
document.getElementById('symbols').checked === true)
{
const charsArray = lowercase.concat(caps).concat(symbols);
password = GeneratePassword(passwordLength, charsArray);
}
else if (document.getElementById('caps').checked === true &&
document.getElementById('numbers').checked === true &&
document.getElementById('symbols').checked === false)
{
const charsArray = lowercase.concat(caps);
password = GeneratePassword(passwordLength, charsArray);
}
else {
password = GeneratePassword(passwordLength, lowercase);
}
正如你所看到的,它是非常重复的。我知道编写好代码的基础之一是DRY,所以我想知道是否有另一种方法可以做到这一点,而不会让它如此重复。我知道switch是if语句的另一种选择,但我认为这不能解决重复问题。
如果有人能提供任何帮助,我将非常感激:)
您有3个布尔条件,这实际上导致9种不同的方式生成密码。但在您的情况下,您可以将逻辑更改为如下内容:
// Copy the lowercase characters
const chars = [...lowercase];
// Add to chars depending on the three conditions
if (useCaps) chars.push(...caps);
if (useNumbers) chars.push(...numbers);
if (useSymbols) chars.push(...symbols);
const password = GeneratePassword(passwordLength, chars);
您应该构建一个字母字符串,然后在随机索引处访问字符。
const UPPER = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
const LOWER = 'abcdefghijklmnopqrstuvwxyz';
const NUMBERS = '0123456789';
const SYMBOLS = '!"#$%&'()*+,-./:;<=>?@[]^`_{|}~';
const defaultOptions = {
includeUpper: true,
includeLower: true,
includeNumbers: true,
includeSymbols: false
};
const randomInt = (min, max) => {
if (max === undefined) { max = min; min = 0; }
return Math.floor(Math.random() * (max - min)) + min;
}
const randomChar = (str) => str[randomInt(str.length)];
const generatePassword = (length, options) => {
const opts = { ...defaultOptions, ...options };
let alphabet = '';
if (opts.includeUpper) alphabet += UPPER;
if (opts.includeLower) alphabet += LOWER;
if (opts.includeNumbers) alphabet += NUMBERS;
if (opts.includeSymbols) alphabet += SYMBOLS;
return new Array(length).fill(0).map(() => randomChar(alphabet)).join('');
};
// Event handler
const handleSubmission = (e) => {
e.preventDefault();
const { target: { elements } } = e;
const generatedPassword = generatePassword(
+elements.size.value,
{
includeUpper: elements.upper.checked,
includeLower: elements.lower.checked,
includeNumbers: elements.numbers.checked,
includeSymbols: elements.symbols.checked
}
);
document.querySelector('#generated').value = generatedPassword;
};
// UI
document.forms['password-generator'].addEventListener('submit', handleSubmission);
html,
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-evenly;
background: #222;
color: #EEE;
font-size: smaller;
}
form input[type="number"] {
width: 3em;
margin-left: 0.5em;
}
.bordered {
border: thin solid #666;
padding: 0.5em;
background: #444;
}
.vertical-form {
display: grid;
grid-template-columns: 1fr;
grid-row-gap: 0.25em;
}
#generated {
font-family: monospace;
}
<form class="bordered vertical-form" name="password-generator">
<label>Length <input type="number" name="size" value="12" /></label>
<label><input type="checkbox" name="upper" checked> Uppercase</label>
<label><input type="checkbox" name="lower" checked> Lowercase</label>
<label><input type="checkbox" name="numbers"> Numbers</label>
<label><input type="checkbox" name="symbols"> Symbols</label>
<button type="submit">Generate Password</button>
</form>
<label>Generated password <input type="text" id="generated" /></label>
您不需要检查每个可能性,只需使用简单的if
语句单独检查每个复选框(而不是if-else
)。只使用lowercase
来重新分配连接的值:
if (document.getElementById('caps').checked === true){
lowercase= lowercase.concat(caps);
}
if (document.getElementById('numbers').checked === true)
{
lowercase= lowercase.concat(numbers);
}
if (document.getElementById('symbols').checked === true)
{
lowercase= lowercase.concat(symbols);
}
password = GeneratePassword(passwordLength, lowercase);
更短的写法是删除括号{}
并删除=== true
,它仍然可以工作:
if (document.getElementById('caps').checked)
lowercase= lowercase.concat(caps);
if (document.getElementById('numbers').checked)
lowercase= lowercase.concat(numbers);
if (document.getElementById('symbols').checked)
lowercase= lowercase.concat(symbols);
password = GeneratePassword(passwordLength, lowercase);
甚至更短的方式来写它,以避免使用if
语句,只是使用js内联条件,类似于三元运算符,但它没有三个语句:
document.getElementById('caps').checked && lowercase= lowercase.concat(caps);
document.getElementById('numbers').checked && lowercase= lowercase.concat(numbers);
document.getElementById('symbols').checked && lowercase = lowercase.concat(symbols);
password = GeneratePassword(passwordLength, lowercase);
它的作用是检查第一个条件document.getElementById('symbols').checked
。如果选中则返回true
,如果未选中则返回false
。
- 如果它被选中(
true
),它将转到第二个内联条件lowercase= lowercase.concat(caps)
。因为它也是一条指令,所以代码将执行该指令。 - 如果未选中(
false
),代码将转到另一行,并对该内联条件执行相同操作。
如果可以适当地维护缩进,则可以始终使用多个嵌套的三元操作符。