如何在 JavaScript 中返回方法



我有多个if语句被调用。我想设置它,以便如果用户取消所有 4 个提示,它会提示他们无效并将它们返回到函数的开头?我试图将其设置为if语句,但无法完全使其正常工作.
我是JavaScript的新手,所以请耐心等待或保持简单。

// Get references to the #generate element
var generateBtn = document.querySelector("#generate");
const myArrayUpper = Array.from(Array(26)).map((e, i) => i + 65);
const alphabetUpper = myArrayUpper.map((x) => String.fromCharCode(x));
const myArrayLower = Array.from(Array(26)).map((e, i) => i + 97);
const alphabetLower = myArrayLower.map((x) => String.fromCharCode(x));
const arrayNumeric = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
const arraySpecialCharacters = ['!', '@', '#', '$', '%', '^', '&', '*', '(', ')'];
function generatePassword() {
var results = "";
var numberOfCharacters = window.prompt("How many characters would you like your password to contain");
var characterQuantity = parseInt(numberOfCharacters);
if (characterQuantity >= 8 && characterQuantity <= 128) {
var lowerCase = window.confirm("click OK to confirm lowercase letter.");
var upperCase = window.confirm("Click OK to confirm uppercase letter.");
var numeric = window.confirm("Click OK to confirm numeric values");
var specialCharacters = window.confirm("Click OK to confirm special characters");
var okayButton = [];
if (upperCase == true) okayButton.push(alphabetUpper);
if (lowerCase == true) okayButton.push(alphabetLower);
if (numeric == true) okayButton.push(arrayNumeric);
if (specialCharacters == true) okayButton.push(arraySpecialCharacters);

for (var i = 0; i < characterQuantity; i++) {
var storeButton = Math.floor(Math.random() * okayButton.length);
var selectedArray = okayButton[storeButton];
results += selectedArray[Math.floor(Math.random() * selectedArray.length)];
// results += alphabetLower[Math.floor(Math.random() *26)];
// results += arrayNumeric[Math.floor(Math.random() *10)];
// results += arraySpecialCharacters[Math.floor(Math.random() *10)];
}
} else {
window.alert('This is an invalid entry. Select an entry between 8 and 128');
return generatePassword();
}
return results;
}
// challenge make it so that if they hit cancel to many times instead of error have it prompt them to do it again
// Write password to the #password input
function writePassword() {
var password = generatePassword();
var passwordText = document.querySelector("#password");
passwordText.value = password;
}
// Add event listener to generate button
generateBtn.addEventListener("click", writePassword);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Password Generator</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="wrapper">
<header>
<h1>Password Generator</h1>
</header>
<div class="card">
<div class="card-header">
<h2>Generate a Password</h2>
</div>
<div class="card-body">
<textarea readonly id="password" placeholder="Your Secure Password" aria-label="Generated Password"></textarea>
</div>
<div class="card-footer">
<button id="generate" class="btn">Generate Password</button>
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>

在提出这些问题的代码周围放置一个循环。如果他们回答确认至少其中一个,请脱离循环。

也几乎不需要像upperCaselowerCase这样的变量。只需直接测试confirm()调用即可。

// Get references to the #generate element
var generateBtn = document.querySelector("#generate");
const myArrayUpper = Array.from(Array(26)).map((e, i) => i + 65);
const alphabetUpper = myArrayUpper.map((x) => String.fromCharCode(x));
const myArrayLower = Array.from(Array(26)).map((e, i) => i + 97);
const alphabetLower = myArrayLower.map((x) => String.fromCharCode(x));
const arrayNumeric = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
const arraySpecialCharacters = ['!', '@', '#', '$', '%', '^', '&', '*', '(', ')'];
function generatePassword() {
var results = "";
var numberOfCharacters = window.prompt("How many characters would you like your password to contain");
var characterQuantity = parseInt(numberOfCharacters);
if (characterQuantity >= 8 && characterQuantity <= 128) {
var okayButton = [];
while (true) {
if (window.confirm("click OK to confirm lowercase letter.")) {
okayButton.push(alphabetLower);
}
if (window.confirm("Click OK to confirm uppercase letter.")) {
okayButton.push(alphabetUpper);
}
if (window.confirm("Click OK to confirm numeric values")) {
okayButton.push(arrayNumeric);
}
if (window.confirm("Click OK to confirm special characters")) {
okayButton.push(arraySpecialCharacters);
}
if (okayButton.length > 0) {
break;
}
alert("You need to confirm at least one kind of character, try again.");
}
for (var i = 0; i < characterQuantity; i++) {
var storeButton = Math.floor(Math.random() * okayButton.length);
var selectedArray = okayButton[storeButton];
results += selectedArray[Math.floor(Math.random() * selectedArray.length)];
// results += alphabetLower[Math.floor(Math.random() *26)];
// results += arrayNumeric[Math.floor(Math.random() *10)];
// results += arraySpecialCharacters[Math.floor(Math.random() *10)];
}
} else {
window.alert('This is an invalid entry. Select an entry between 8 and 128');
return generatePassword();
}
return results;
}
// challenge make it so that if they hit cancel to many times instead of error have it prompt them to do it again
// Write password to the #password input
function writePassword() {
var password = generatePassword();
var passwordText = document.querySelector("#password");
passwordText.value = password;
}
// Add event listener to generate button
generateBtn.addEventListener("click", writePassword);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Password Generator</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="wrapper">
<header>
<h1>Password Generator</h1>
</header>
<div class="card">
<div class="card-header">
<h2>Generate a Password</h2>
</div>
<div class="card-body">
<textarea readonly id="password" placeholder="Your Secure Password" aria-label="Generated Password"></textarea>
</div>
<div class="card-footer">
<button id="generate" class="btn">Generate Password</button>
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>

出于教学目的,下面是一个重构:

const possibleCharacters = [
...confirm('Numeric?') && '0123456789' || [],
...confirm('Lower case?') && 'abcdefghijklmnopqrstuvwxyz' || [],
...confirm('Upper case?') && 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' || [],
...confirm('Special?') && '!@#$%^&*()' || []
];
alert('Your password:n' + 
[...crypto.getRandomValues(
new Uint32Array(
Number.parseInt(prompt('Character count?'))
)
)].map(i => possibleCharacters[i % possibleCharacters.length]).join('')
);

仅此而已!

解释:

短路评估

...confirm('Numeric?') && '0123456789' || []

让我们只看一下这一行的布尔部分,看看它在 JavaScript 解释器中的外观。

<true or false> AND truthy-value-a OR truthy-value-b

也就是说,confirm()将返回truefalse. 字符串'0123456789'真实的,只是所有非空字符串都是。 空数组是真实的,就像所有对象一样。

当计算falseANDtrue时,解释器马上知道语句是false的,因为第一项是false下一项永远不会被评估为真实性。 更重要的是,false现在实际上是该语句的返回值。 如果第一项true并且下一项是真实的,则下一项是返回值。

因此,true && 'some string'评估为'some string'. 这意味着,如果用户确认对话框,则true对话框项,并返回字符串。

如果用户不确认对话框,则false,永远不会计算字符串(由于 AND&&),我们继续 OR||falsetrue的计算结果为truefalseOR 某个真值计算为某个真值由于空数组是真实的,因此返回它。 我们总是必须在这里返回可迭代的东西的原因将在下一节中显而易见。

点差运算符

省略号...是 JavaScript 中的传播运算符。 如果我们想制作一个数组数组...

[
...[1, 2, 3],
...[4, 5, 6]
] // Basically the same as [1, 2, 3, 4, 5, 6]

不过很酷的是字符串也是可迭代的:

[...'asdf'] // Synonymous with ['a', 's', 'd', 'f']

所以上面,对于每个字符集,我们要么迭代一个可能的字符串,要么迭代一个空数组。 这一切都被合并到一个大的possibleCharacters数组中。

随机值的加密

[...crypto.getRandomValues(
new Uint32Array(
Number.parseInt(prompt('Character count?'))
)
)]

在这里,我们提示用户输入字符数。 使用该响应,我们创建一个新的 TypedArray 来存储一些大的 32 位无符号整数。 我们使用crypto.getRandomValues()填充该数组,该函数的返回值是我们的 TypedArray。

为什么选择加密货币? 这种用法可能有点矫枉过正,但它便于返回安全的随机数。 其他随机数生成器在理论上和特定条件下更具可预测性。

那么,如果我们有一个数字数组,为什么我们需要运算符和数组[... ]外部扩散? 这只是从类型化数组中获取非类型化常规数组的快速方法。 这很重要,因为我们将在下一步中将数组.map()到我们的密码。

Array.map()

这个,你可能以前见过。 这很简单。 对于数组中的每个项,运行回调函数并返回一个新数组,其中包含所有这些函数调用的返回值。

在这里,我们将大的随机数映射到possibleCharacters数组中的字符。 如何?。。。

模运算符 (%)

如果你把一个数字除以另一个数字,但只想要整数结果,剩下的是什么? 你可以通过模数找到它。

0 % 2 // 0
1 % 2 // 1
2 % 2 // 0
3 % 2 // 1
4 % 2 // 0
// etc.

那么,这对我们有什么帮助呢? 好吧,其中一些随机数真的很大,例如25960038633979143875. 我们无法获取少于 100 个项目的数组的第 985,031,522 个项目。 但是,使用模运算符,我们可以保持随机性,同时将其保持在数组中。 把它想象成一个游戏轮,参赛者给它一个非常艰难的拉动。 轮子可能会旋转很多次,但它仍然落在一个随机的地方。

2616031673 % 72 // 17
3016112995 % 72 // 19
874672118 % 72 // 62
// etc.

Array.join()

最后,虽然我们将有一个字符数组,但我们需要将它们作为一个字符串重新推到一起。 这就是.join()的用武之地。 无论第一个参数是什么,都是插入数组每个项目之间的字符串。 如果您像我们在这里一样使用空字符串,则所有字符都会放在一起。

我希望您(或某人)发现这些项目的解释对您有所帮助!

你的问题有点难以理解,但我会尝试回应 1) 标题,然后 2) 我认为你基于代码的意思。

  1. "如何在 JavaScript 中返回一个方法?" 当你写return generatePassword();时,你返回了调用generatePassword的结果。但是,您可以轻松地返回generatePassword本身,这是像javascript这样的语言中的常见做法,通过编写return generatePassword;。然后,调用方可以根据需要运行返回的函数。Javascript具有第一类函数,这意味着函数可以像对待任何其他变量一样对待。术语"方法"通常保留给作为类成员的函数,所以我在这个描述中只坚持使用"函数"。
  2. 我想您是在询问在不满足某些条件时如何重新运行一系列提示。其他用户建议循环是解决此问题的最佳方法,我同意。但是,也可以说类似if (conditions not met) { return generatePassword(); },就像您在长度检查的else分支中所做的那样。与循环相比,递归可能很昂贵,因此,循环(从广义上讲)是首选,但您再次简单地调用generatePassword的倾向并没有错。

如果我正确理解了你的问题,那么在一段时间循环中嵌套四个if就足够了?

将它们初始化为 false,如果在要求用户选择其中一个选项以使其为 true 时它们都保持 false,则重新启动循环。

if(characterQuantity >= 8 && characterQuantity <= 128) {
var lowerCase = false
var upperCase = false
var numeric = false
var specialCharacters = false
while (!lowerCase && !upperCase && !numeric && !specialCharacters) {
lowerCase = window.confirm("click OK to confirm lowercase letter."); 
upperCase = window.confirm("Click OK to confirm uppercase letter.");
numeric = window.confirm("Click OK to confirm numeric values");
specialCharacters = window.confirm("Click OK to confirm special characters");
if (!lowerCase && !upperCase && !numeric && !specialCharacters) window.alert("It is not valid to not select any of these. Try again")
}

编辑:我认为您可以使用对象文字来使代码更干净一些,但这确实是一种增强,并不是解决您的问题所必需的。

所以我让它工作的一种方法是设置一个 if 语句,如果没有任何值为真,请使用下面这个:

if (upperCase || lowerCase || numeric || specialCharacters) {
for (var i = 0; i < characterQuantity; i++) {
var storeButton = Math.floor(Math.random() * okayButton.length);
var selectedArray = okayButton[storeButton];
results += selectedArray[Math.floor(Math.random() * selectedArray.length)];
}
} else {
window.alert('This is an invalid entry. Select at least ONE to proceed');
return generatePassword();

最新更新