如何在另一个函数中获取函数内部的var?
How to obtain a var inside a function in another function?
在我的游戏中,玩家可以选择掷 2、3 或 4 个骰子,然后选择号码。将掷骰子,最大的数字获胜。但是,当用户选择要滚动的 3 或 4 个骰子时,我无法在按下提交按钮时触发的事件监听器中获取 var randomNumber1
- var randomNumber4
。我需要那些 var
才能继续编码。有人可以帮忙吗谢谢。
在我的 javascript 代码的最后 4 行中,if (noOfChoices === "3")
、console.log(userChoices);
没有打印,即使上述 if (noOfChoices === "2")
的情况有效。 chrome 开发工具上显示的错误消息是:
index.js:91 Uncaught ReferenceError: randomNumber1 is not defined
at HTMLAnchorElement.<anonymous> (index.js:91)
谁能帮忙谢谢。
这是我的 javascript 代码:
function diceRoll() {
var randomNumber1 = Math.floor(Math.random() * 6 + 1);
var Image1 = "dice" + randomNumber1 + ".png";
document.querySelectorAll("img")[1].setAttribute("src", Image1);
var randomNumber2 = Math.floor(Math.random() * 6 + 1);
var Image2 = "dice" + randomNumber2 + ".png";
document.querySelectorAll("img")[2].setAttribute("src", Image2);
var randomNumber3 = Math.floor(Math.random() * 6 + 1);
var Image3 = "dice" + randomNumber3 + ".png";
document.querySelectorAll("img")[3].setAttribute("src", Image3);
var randomNumber3 = Math.floor(Math.random() * 6 + 1);
var Image4 = "dice" + randomNumber4 + ".png";
document.querySelectorAll("img")[4].setAttribute("src", Image4);
}
// Storing user noOfChoices
let links = document.querySelectorAll('#list li')
links.forEach((el) => {
el.addEventListener('click', (event) => {
let numberOfChoices = event.target.innerText
document.getElementById('dropdownMenu').innerHTML = `${numberOfChoices}<span class="caret"></span>`)})
// Responding to Submit
document.getElementById("submit").addEventListener("click", function(e) {
e.preventDefault();
// Storing Data into variables
var choice1 = $("#choice1").val();
var choice2 = $("#choice2").val();
var choice3 = $("#choice3").val();
var choice4 = $("#choice4").val();
var noOfChoices = $("#dropdownMenu").text();
var userChoices = [];
// Displaying no. of dices that user chose
if (noOfChoices === "2") {
$("#caption1, #caption2").removeClass("invisible");
$("#caption3, #caption4").addClass("invisible");
}
if (noOfChoices === "3") {
$("#caption1, #caption2, #caption3").removeClass("invisible");
$("#caption4").addClass("invisible");
}
if (noOfChoices === "4") {
$(".caption").removeClass("invisible");
}
$("#submit").html("Again");
// Rolling Dice
diceRoll();
// Determining Winner
if (noOfChoices === "2") {if (randomNumber1 > randomNumber2) {$("#title").html(choice1 + " wins! ");}
else if (randomNumber2 > randomNumber1) {$("#title").html(choice2 + " wins! ");}
else if (randomNumber2 = randomNumber1){$("#title").html("Oops, try again!");}
}
if (noOfChoices === "3") {userChoices.push(randomNumber1, randomNumber2,randomNumber3);
console.log(userChoices);
}
})}
这是我的 html:
<head>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</head>
<body>
<div class="container-of-images">
<img src="chick2.png">
<figure>
<img id="img1" class="dice" src="dice6.png">
<figcaption class="caption" id="caption1">Choice 1</figcaption>
</figure>
<figure>
<img id="img2" class="dice" src="dice6.png">
<figcaption class="caption" id="caption2">Choice 2</figcaption>
</figure>
<figure class="threeChoices">
<img id="img3" class="dice" src="dice6.png">
<figcaption class="caption" id="caption3">Choice 3</figcaption>
</figure>
<figure class="fourChoices">
<img id="img4" class="dice" src="dice6.png">
<figcaption class="caption" id="caption4">Choice 4</figcaption>
</figure>
<img src="chick1.png">
</div>
<div class="container-of-forms">
<!-- Dropdown Button -->
<div class="dropdown">
<button class="btn btn-info dropdown-toggle" type="button" id="dropdownMenu" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
0
<span class="caret"></span>
</button>
<ul id="list" class="dropdown-menu dropdown-info" aria-labelledby="dropdownMenu">
<li><a href="#">2</a></li>
<li><a href="#">3</a></li>
<li><a href="#">4</a></li>
</ul>
<!-- Input Text Fields -->
<div class="container-inner"> <br>
<input class="text-input-box" id="choice1" type="text" name="" value="" placeholder="Choice 1"> <br>
<input class="text-input-box" id="choice2" type="text" name="" value="" placeholder="Choice 2"> <br>
<input class="text-input-box invisible threeChoices" id="choice3" type="text" name="" value="" placeholder="Choice 3"> <br>
<input class="text-input-box invisible fourChoices" id="choice4" type="text" name="" value="" placeholder="Choice 4">
</div>
</div>
</div>
<h5>The bigger number wins!</h5>
<!-- Submit Button -->
<a href="" id="submit" class="btn btn-info btn-lg" role="button">Go</a>
</div>
</body>
您不能引用这些值,您可以return这些值并使用它们。简单的方法是使用数组。清理后的代码如下所示
function rollResult () {
return Math.floor(Math.random() * 6 + 1);
}
function diceRoll() {
var images = document.querySelectorAll("img");
const dice = [];
for (var i = 0; i<4; i++) {
var number = rollResult();
dice[i] = number;
images[i+1].src = "dice" + number + ".png";
}
return dice;
}
var diceResult = diceRoll();
console.log(1, diceResult[0]);
console.log(2, diceResult[1]);
console.log(3, diceResult[2]);
console.log(4, diceResult[3]);
您需要解决语法错误。此答案仅提供了另一种获取那些重要 randomNumber
值的方式,您稍后需要使用这些值。
正如我们已经在评论部分强调的那样,您无法在 Javascript 中直接访问该函数之外的函数范围变量。您可以采用多种方法来实现这一点...这是其中之一:
让我们 diceRoll()
到 return roll 的 resultObj,如下所示:
function diceRoll() {
var randomNumber1 = Math.floor(Math.random() * 6 + 1);
var Image1 = "dice" + randomNumber1 + ".png";
document.querySelectorAll("img")[1].setAttribute("src", Image1);
var randomNumber2 = Math.floor(Math.random() * 6 + 1);
var Image2 = "dice" + randomNumber2 + ".png";
document.querySelectorAll("img")[2].setAttribute("src", Image2);
var randomNumber3 = Math.floor(Math.random() * 6 + 1);
var Image3 = "dice" + randomNumber3 + ".png";
document.querySelectorAll("img")[3].setAttribute("src", Image3);
var randomNumber4 = Math.floor(Math.random() * 6 + 1);
var Image4 = "dice" + randomNumber4 + ".png";
document.querySelectorAll("img")[4].setAttribute("src", Image4);
return {
One: {
randomNumber: randomNumber1,
image: Image1
},
Two: {
randomNumber: randomNumber2,
image: Image2
},
Three: {
randomNumber: randomNumber3,
image: Image3
},
Four: {
randomNumber: randomNumber4,
image: Image4
}
}
}
您会注意到我 return 用 4 个键编辑了一个对象,每个键代表一个骰子。每个骰子都有属性 randomNumber
和 image
。这样你就可以调用 diceRoll
并稍后通过这样做访问结果:
var result = diceRoll();
骰子已掷出,现在我们可以通过使用 result
访问骰子的属性来获得结果...您可以这样做:
// Determining Winner
if (noOfChoices === "2") {if (result.One.randomNumber > result.Two.randomNumber) {$("#title").html(choice1 + " wins! ");}
else if (result.Two.randomNumber > result.One.randomNumber ) {$("#title").html(choice2 + " wins! ");}
else if (result.Two.randomNumber= result.One.randomNumber){$("#title").html("Oops, try again!");}
}
这适用于骰子 3 和 4。
这是另一个更简单的版本:
function diceRoll() {
let DiceKeys = ["One","Two","Three","Four"];
let resultObject = {};
DiceKeys.forEach((keyName, index)=>{
let diceRandomNum = Math.floor(Math.random() * 6 + 1);
let diceImageSrc = "dice" + diceRandomNum + ".png";
document.querySelectorAll("img")[++index].setAttribute("src", diceImageSrc);
resultObject[keyName] = {
randomNumber: diceRandomNum,
imageSrc : diceImageSrc
};
});
return resultObject;
}
您可能不知道,但您问的是一个非常非常重要的 Javascript 概念,称为“作用域”。
变量有“作用域”。将作用域视为一组可以访问变量的上下文。
变量对其“当前范围”及其下的所有范围可见。始终存在“全局”范围,a.k.a。最外层的运行时间环境。如果您查看 diceRoll
函数定义后的第一行可执行代码,您将看到一个全局范围变量的示例:links
。变量 links
可以从 程序中的任何地方访问 只要您不使用某种模块捆绑器来修改幕后范围(看起来您是在这里做一些非常基本的编程,所以让我们暂时忘记它)。
除了全局作用域,我们还有其他作用域。有一个对您来说非常重要:函数作用域。
函数创建自己的作用域。这意味着函数外部的任何内容都无法访问函数内部的内容。它有自己的小 self-defined 作用域。您在其中定义的任何变量都无法在该函数之外访问。如果您考虑原因,就会开始理解:函数是临时代码。他们 运行,然后他们就完成了。每次调用函数时,都会创建一个新作用域,处理函数逻辑,然后销毁所有变量引用,只要它们没有传回调用上下文即可。这是设计使然。
然后,您在这里所做的是创建变量,例如 randomNumber1
根本不存在 函数范围之外 [=12] =].
现在,更高级的编程技术会争辩说您应该永远不要创建全局变量,我保证您最终会学会遵守这些内容。但是现在,为了让您开始了解范围,解决您问题的最简单方法是 定义您的变量 在 之外diceRoll
函数,并从 内部 中 将您的值分配给它们 。基本上,这将解决您的问题:
// Here, you **define** your variables. This "creates" them, but does not assign them values.
var randomNumber1;
var randomNumber2;
var randomNumber3;
var randomNumber4;
var image1;
var image2;
var image3;
var image4;
// When code execution reaches this point, you could do something like this:
console.log(randomNumber1);
// ^ the above line would log `undefined` to the console, because the variable exists but has no value assigned to it. Great! We're all set, now all your global scope stuff further down can access these variables!
function diceRoll() {
// Now in here, you simply remove the *var* keyword, since you don't want to *create new variables*, you want to *assign values to the existing ones*. If you use the *var* keyword here, it will create a *new* variable with the same name, but only within the function scope. You will still have the same problem.
randomNumber1 = Math.floor(Math.random() * 6 + 1);
image1 = "dice" + randomNumber1 + ".png";
document.querySelectorAll("img")[1].setAttribute("src", Image1);
randomNumber2 = Math.floor(Math.random() * 6 + 1);
image2 = "dice" + randomNumber2 + ".png";
document.querySelectorAll("img")[2].setAttribute("src", Image2);
randomNumber3 = Math.floor(Math.random() * 6 + 1);
image3 = "dice" + randomNumber3 + ".png";
document.querySelectorAll("img")[3].setAttribute("src", Image3);
randomNumber3 = Math.floor(Math.random() * 6 + 1);
image4 = "dice" + randomNumber3 + ".png";
document.querySelectorAll("img")[4].setAttribute("src", Image4);
}
请注意,作为一个小的语义选择,我以符合行业标准约定的驼峰式(首字母小写)声明了您的 Image[x] 变量名称。
最后但同样重要的是,让我们回过头来 re-read 这里重要的事情可以帮助您找出问题:错误本身:
index.js:91 Uncaught ReferenceError: randomNumber1 is not defined
at HTMLAnchorElement.<anonymous> (index.js:91)
让我们将其翻译成英文:
Uncaught ReferenceError
“Uncaught”表示发生了错误(意味着您遇到了执行错误,因为您尝试执行某些由于某种原因而无法执行的操作)。什么是未捕获的?一个错误(它总是一个错误),特别是 ReferenceError
类型。
正如我们乐于助人的朋友 MDN 告诉我们的:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError
The ReferenceError object represents an error when a non-existent variable is referenced.
基本上,您试图访问一个尚未在当前范围(在您的情况下为全局范围)中定义的变量。
最后:randomNumber1 is not defined
<-- 无需翻译。简而言之,尝试引用变量 (randomNumber1) 时出错,因为它未定义。错误的后半部分告诉你 where:
at HTMLAnchorElement.<anonymous> (index.js:91)
<-- index.js on line 91。你可以通过这个来了解你在什么scope,这样你就可以正确引用变量在该范围内解决您的问题。
at HTMLAnchorElement.<anonymous>
指的是调用堆栈中的当前步骤及其上下文 - 但这更复杂,您现在可以忽略它。
所以,总结一下:
我们已将您要访问的变量的声明移到外部您的函数范围,并保留对这些变量赋值,这样它仍然会在内部你的函数中发生。理解这一点非常重要,我强烈建议您阅读一些有关 Javascript 以及函数作用域和闭包的内容。如果你想成为入门级 JS 开发人员,你 绝对需要理解这个概念 。
很高兴回答您的任何问题。祝你好运!
编辑:
@Mosia Thabo 的回答也是一个很好的例子,我认为,“更正确的解决方案”。我没有故意提供该解决方案,那是为了让这个解决方案与您的问题真正相关,即使您不知道。请注意,我提到过“全局范围变量是你想要始终避免的东西”,你无疑会遇到“全局变量是邪恶的”这句话。他们是。
我的例子是为了简化范围的概念,我认为这是在这里学习的重要一课。 Mosia 的回答 我将如何处理它 - 这个函数基本上变成了你所谓的生成器,给你一个结果 se 作为 return 值。但是 return 值会增加混淆,所以我将那部分省略了。
范围。学。关于。范围。
在我的游戏中,玩家可以选择掷 2、3 或 4 个骰子,然后选择号码。将掷骰子,最大的数字获胜。但是,当用户选择要滚动的 3 或 4 个骰子时,我无法在按下提交按钮时触发的事件监听器中获取 var randomNumber1
- var randomNumber4
。我需要那些 var
才能继续编码。有人可以帮忙吗谢谢。
在我的 javascript 代码的最后 4 行中,if (noOfChoices === "3")
、console.log(userChoices);
没有打印,即使上述 if (noOfChoices === "2")
的情况有效。 chrome 开发工具上显示的错误消息是:
index.js:91 Uncaught ReferenceError: randomNumber1 is not defined
at HTMLAnchorElement.<anonymous> (index.js:91)
谁能帮忙谢谢。
这是我的 javascript 代码:
function diceRoll() {
var randomNumber1 = Math.floor(Math.random() * 6 + 1);
var Image1 = "dice" + randomNumber1 + ".png";
document.querySelectorAll("img")[1].setAttribute("src", Image1);
var randomNumber2 = Math.floor(Math.random() * 6 + 1);
var Image2 = "dice" + randomNumber2 + ".png";
document.querySelectorAll("img")[2].setAttribute("src", Image2);
var randomNumber3 = Math.floor(Math.random() * 6 + 1);
var Image3 = "dice" + randomNumber3 + ".png";
document.querySelectorAll("img")[3].setAttribute("src", Image3);
var randomNumber3 = Math.floor(Math.random() * 6 + 1);
var Image4 = "dice" + randomNumber4 + ".png";
document.querySelectorAll("img")[4].setAttribute("src", Image4);
}
// Storing user noOfChoices
let links = document.querySelectorAll('#list li')
links.forEach((el) => {
el.addEventListener('click', (event) => {
let numberOfChoices = event.target.innerText
document.getElementById('dropdownMenu').innerHTML = `${numberOfChoices}<span class="caret"></span>`)})
// Responding to Submit
document.getElementById("submit").addEventListener("click", function(e) {
e.preventDefault();
// Storing Data into variables
var choice1 = $("#choice1").val();
var choice2 = $("#choice2").val();
var choice3 = $("#choice3").val();
var choice4 = $("#choice4").val();
var noOfChoices = $("#dropdownMenu").text();
var userChoices = [];
// Displaying no. of dices that user chose
if (noOfChoices === "2") {
$("#caption1, #caption2").removeClass("invisible");
$("#caption3, #caption4").addClass("invisible");
}
if (noOfChoices === "3") {
$("#caption1, #caption2, #caption3").removeClass("invisible");
$("#caption4").addClass("invisible");
}
if (noOfChoices === "4") {
$(".caption").removeClass("invisible");
}
$("#submit").html("Again");
// Rolling Dice
diceRoll();
// Determining Winner
if (noOfChoices === "2") {if (randomNumber1 > randomNumber2) {$("#title").html(choice1 + " wins! ");}
else if (randomNumber2 > randomNumber1) {$("#title").html(choice2 + " wins! ");}
else if (randomNumber2 = randomNumber1){$("#title").html("Oops, try again!");}
}
if (noOfChoices === "3") {userChoices.push(randomNumber1, randomNumber2,randomNumber3);
console.log(userChoices);
}
})}
这是我的 html:
<head>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</head>
<body>
<div class="container-of-images">
<img src="chick2.png">
<figure>
<img id="img1" class="dice" src="dice6.png">
<figcaption class="caption" id="caption1">Choice 1</figcaption>
</figure>
<figure>
<img id="img2" class="dice" src="dice6.png">
<figcaption class="caption" id="caption2">Choice 2</figcaption>
</figure>
<figure class="threeChoices">
<img id="img3" class="dice" src="dice6.png">
<figcaption class="caption" id="caption3">Choice 3</figcaption>
</figure>
<figure class="fourChoices">
<img id="img4" class="dice" src="dice6.png">
<figcaption class="caption" id="caption4">Choice 4</figcaption>
</figure>
<img src="chick1.png">
</div>
<div class="container-of-forms">
<!-- Dropdown Button -->
<div class="dropdown">
<button class="btn btn-info dropdown-toggle" type="button" id="dropdownMenu" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
0
<span class="caret"></span>
</button>
<ul id="list" class="dropdown-menu dropdown-info" aria-labelledby="dropdownMenu">
<li><a href="#">2</a></li>
<li><a href="#">3</a></li>
<li><a href="#">4</a></li>
</ul>
<!-- Input Text Fields -->
<div class="container-inner"> <br>
<input class="text-input-box" id="choice1" type="text" name="" value="" placeholder="Choice 1"> <br>
<input class="text-input-box" id="choice2" type="text" name="" value="" placeholder="Choice 2"> <br>
<input class="text-input-box invisible threeChoices" id="choice3" type="text" name="" value="" placeholder="Choice 3"> <br>
<input class="text-input-box invisible fourChoices" id="choice4" type="text" name="" value="" placeholder="Choice 4">
</div>
</div>
</div>
<h5>The bigger number wins!</h5>
<!-- Submit Button -->
<a href="" id="submit" class="btn btn-info btn-lg" role="button">Go</a>
</div>
</body>
您不能引用这些值,您可以return这些值并使用它们。简单的方法是使用数组。清理后的代码如下所示
function rollResult () {
return Math.floor(Math.random() * 6 + 1);
}
function diceRoll() {
var images = document.querySelectorAll("img");
const dice = [];
for (var i = 0; i<4; i++) {
var number = rollResult();
dice[i] = number;
images[i+1].src = "dice" + number + ".png";
}
return dice;
}
var diceResult = diceRoll();
console.log(1, diceResult[0]);
console.log(2, diceResult[1]);
console.log(3, diceResult[2]);
console.log(4, diceResult[3]);
您需要解决语法错误。此答案仅提供了另一种获取那些重要 randomNumber
值的方式,您稍后需要使用这些值。
正如我们已经在评论部分强调的那样,您无法在 Javascript 中直接访问该函数之外的函数范围变量。您可以采用多种方法来实现这一点...这是其中之一:
让我们 diceRoll()
到 return roll 的 resultObj,如下所示:
function diceRoll() {
var randomNumber1 = Math.floor(Math.random() * 6 + 1);
var Image1 = "dice" + randomNumber1 + ".png";
document.querySelectorAll("img")[1].setAttribute("src", Image1);
var randomNumber2 = Math.floor(Math.random() * 6 + 1);
var Image2 = "dice" + randomNumber2 + ".png";
document.querySelectorAll("img")[2].setAttribute("src", Image2);
var randomNumber3 = Math.floor(Math.random() * 6 + 1);
var Image3 = "dice" + randomNumber3 + ".png";
document.querySelectorAll("img")[3].setAttribute("src", Image3);
var randomNumber4 = Math.floor(Math.random() * 6 + 1);
var Image4 = "dice" + randomNumber4 + ".png";
document.querySelectorAll("img")[4].setAttribute("src", Image4);
return {
One: {
randomNumber: randomNumber1,
image: Image1
},
Two: {
randomNumber: randomNumber2,
image: Image2
},
Three: {
randomNumber: randomNumber3,
image: Image3
},
Four: {
randomNumber: randomNumber4,
image: Image4
}
}
}
您会注意到我 return 用 4 个键编辑了一个对象,每个键代表一个骰子。每个骰子都有属性 randomNumber
和 image
。这样你就可以调用 diceRoll
并稍后通过这样做访问结果:
var result = diceRoll();
骰子已掷出,现在我们可以通过使用 result
访问骰子的属性来获得结果...您可以这样做:
// Determining Winner
if (noOfChoices === "2") {if (result.One.randomNumber > result.Two.randomNumber) {$("#title").html(choice1 + " wins! ");}
else if (result.Two.randomNumber > result.One.randomNumber ) {$("#title").html(choice2 + " wins! ");}
else if (result.Two.randomNumber= result.One.randomNumber){$("#title").html("Oops, try again!");}
}
这适用于骰子 3 和 4。
这是另一个更简单的版本:
function diceRoll() {
let DiceKeys = ["One","Two","Three","Four"];
let resultObject = {};
DiceKeys.forEach((keyName, index)=>{
let diceRandomNum = Math.floor(Math.random() * 6 + 1);
let diceImageSrc = "dice" + diceRandomNum + ".png";
document.querySelectorAll("img")[++index].setAttribute("src", diceImageSrc);
resultObject[keyName] = {
randomNumber: diceRandomNum,
imageSrc : diceImageSrc
};
});
return resultObject;
}
您可能不知道,但您问的是一个非常非常重要的 Javascript 概念,称为“作用域”。
变量有“作用域”。将作用域视为一组可以访问变量的上下文。
变量对其“当前范围”及其下的所有范围可见。始终存在“全局”范围,a.k.a。最外层的运行时间环境。如果您查看 diceRoll
函数定义后的第一行可执行代码,您将看到一个全局范围变量的示例:links
。变量 links
可以从 程序中的任何地方访问 只要您不使用某种模块捆绑器来修改幕后范围(看起来您是在这里做一些非常基本的编程,所以让我们暂时忘记它)。
除了全局作用域,我们还有其他作用域。有一个对您来说非常重要:函数作用域。
函数创建自己的作用域。这意味着函数外部的任何内容都无法访问函数内部的内容。它有自己的小 self-defined 作用域。您在其中定义的任何变量都无法在该函数之外访问。如果您考虑原因,就会开始理解:函数是临时代码。他们 运行,然后他们就完成了。每次调用函数时,都会创建一个新作用域,处理函数逻辑,然后销毁所有变量引用,只要它们没有传回调用上下文即可。这是设计使然。
然后,您在这里所做的是创建变量,例如 randomNumber1
根本不存在 函数范围之外 [=12] =].
现在,更高级的编程技术会争辩说您应该永远不要创建全局变量,我保证您最终会学会遵守这些内容。但是现在,为了让您开始了解范围,解决您问题的最简单方法是 定义您的变量 在 之外diceRoll
函数,并从 内部 中 将您的值分配给它们 。基本上,这将解决您的问题:
// Here, you **define** your variables. This "creates" them, but does not assign them values.
var randomNumber1;
var randomNumber2;
var randomNumber3;
var randomNumber4;
var image1;
var image2;
var image3;
var image4;
// When code execution reaches this point, you could do something like this:
console.log(randomNumber1);
// ^ the above line would log `undefined` to the console, because the variable exists but has no value assigned to it. Great! We're all set, now all your global scope stuff further down can access these variables!
function diceRoll() {
// Now in here, you simply remove the *var* keyword, since you don't want to *create new variables*, you want to *assign values to the existing ones*. If you use the *var* keyword here, it will create a *new* variable with the same name, but only within the function scope. You will still have the same problem.
randomNumber1 = Math.floor(Math.random() * 6 + 1);
image1 = "dice" + randomNumber1 + ".png";
document.querySelectorAll("img")[1].setAttribute("src", Image1);
randomNumber2 = Math.floor(Math.random() * 6 + 1);
image2 = "dice" + randomNumber2 + ".png";
document.querySelectorAll("img")[2].setAttribute("src", Image2);
randomNumber3 = Math.floor(Math.random() * 6 + 1);
image3 = "dice" + randomNumber3 + ".png";
document.querySelectorAll("img")[3].setAttribute("src", Image3);
randomNumber3 = Math.floor(Math.random() * 6 + 1);
image4 = "dice" + randomNumber3 + ".png";
document.querySelectorAll("img")[4].setAttribute("src", Image4);
}
请注意,作为一个小的语义选择,我以符合行业标准约定的驼峰式(首字母小写)声明了您的 Image[x] 变量名称。
最后但同样重要的是,让我们回过头来 re-read 这里重要的事情可以帮助您找出问题:错误本身:
index.js:91 Uncaught ReferenceError: randomNumber1 is not defined
at HTMLAnchorElement.<anonymous> (index.js:91)
让我们将其翻译成英文:
Uncaught ReferenceError
“Uncaught”表示发生了错误(意味着您遇到了执行错误,因为您尝试执行某些由于某种原因而无法执行的操作)。什么是未捕获的?一个错误(它总是一个错误),特别是 ReferenceError
类型。
正如我们乐于助人的朋友 MDN 告诉我们的:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError
The ReferenceError object represents an error when a non-existent variable is referenced.
基本上,您试图访问一个尚未在当前范围(在您的情况下为全局范围)中定义的变量。
最后:randomNumber1 is not defined
<-- 无需翻译。简而言之,尝试引用变量 (randomNumber1) 时出错,因为它未定义。错误的后半部分告诉你 where:
at HTMLAnchorElement.<anonymous> (index.js:91)
<-- index.js on line 91。你可以通过这个来了解你在什么scope,这样你就可以正确引用变量在该范围内解决您的问题。
at HTMLAnchorElement.<anonymous>
指的是调用堆栈中的当前步骤及其上下文 - 但这更复杂,您现在可以忽略它。
所以,总结一下:
我们已将您要访问的变量的声明移到外部您的函数范围,并保留对这些变量赋值,这样它仍然会在内部你的函数中发生。理解这一点非常重要,我强烈建议您阅读一些有关 Javascript 以及函数作用域和闭包的内容。如果你想成为入门级 JS 开发人员,你 绝对需要理解这个概念 。
很高兴回答您的任何问题。祝你好运!
编辑: @Mosia Thabo 的回答也是一个很好的例子,我认为,“更正确的解决方案”。我没有故意提供该解决方案,那是为了让这个解决方案与您的问题真正相关,即使您不知道。请注意,我提到过“全局范围变量是你想要始终避免的东西”,你无疑会遇到“全局变量是邪恶的”这句话。他们是。
我的例子是为了简化范围的概念,我认为这是在这里学习的重要一课。 Mosia 的回答 我将如何处理它 - 这个函数基本上变成了你所谓的生成器,给你一个结果 se 作为 return 值。但是 return 值会增加混淆,所以我将那部分省略了。
范围。学。关于。范围。