在同一字符串中生成20个不同随机字符的JavaScript实现
Hey Dylan, let's break down why your code is printing the same random character 20 times, and how to fix it easily!
What's Going Wrong?
Your current code has two key issues:
- Static random value: The
insertvariable is calculated once before the loop starts. EverysetTimeoutcallback uses this single pre-generated value, hence the repeated character. - Closure behavior: Even if you tried to update
insertinside the loop, the callbacks would still reference the final value ofinsert(thanks to JavaScript closure capturing variables by reference, not value—unless you use block-scoped variables).
How to Fix It
There are two straightforward solutions to get 20 unique random characters:
Solution 1: Generate Random Characters Inside the Callback
Move the random character generation directly into the setTimeout callback. This way, every time the callback runs, it creates a new random character:
var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; var str = "0"; for (var i = 0; i < 20; i++) { setTimeout(function() { // Generate a new random character each time the callback executes var insert = letters.charAt(Math.floor(Math.random() * letters.length)); var newStr = str.replace(/./, insert); console.log(newStr); }, 50 * i); }
Solution 2: Use Block-Scoped Variables with let
If you prefer to pre-generate the random values during the loop, use let (instead of var) to declare insert inside the loop. let creates a new variable binding for each loop iteration, so each callback captures a unique value:
var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; var str = "0"; for (let i = 0; i < 20; i++) { // `let` ensures each iteration has its own `insert` value let insert = letters.charAt(Math.floor(Math.random() * letters.length)); setTimeout(function() { var newStr = str.replace(/./, insert); console.log(newStr); }, 50 * i); }
Do You Need a Custom Callback Function?
Nope! You don't need to add any extra custom callback functions here. The setTimeout callback itself is sufficient to handle the per-iteration logic. Custom callbacks are typically used for more complex scenarios (like chaining dependent asynchronous operations), which isn't necessary for your current goal of generating 20 unique random characters.
内容的提问来源于stack exchange,提问作者Dylan Hsiao

