简体   繁体   English

变量只能在函数中本地运行,而不能在全局中运行-Javascript

[英]Variables Only Work Locally in a Function, Not globally - Javascript

I have had this issue before on another project. 我在另一个项目上遇到过这个问题。 When I include my variables in a function with local scope , the function is able to run. 当我将变量包含在具有局部作用域的函数中时,该函数可以运行。 When I put the variable outside of function with global scope , the function does not interpret the variables and does not run. 当我将变量置于具有全局作用域的函数之外时,该函数不会解释变量并且不会运行。 I've tried passing the global variables into my functions and it does not run. 我尝试将全局变量传递到函数中,但它没有运行。

This example is a snippet of a countdown timer I was working on: 此示例是我正在使用的倒数计时器的摘要:

LOCAL SCOPE (FUNCTION RUNS) http://jsbin.com/leyicubegu/2/edit 局部范围(功能运行) http://jsbin.com/leyicubegu/2/edit

function addTime() {

     var userTime = timeInput.value;
     var timeString = userTime.toString();
     var timeArray = timeString.split("");
     var hundrethsValue = timeArray[6].concat(timeArray[7]);
     var secondsValue = timeArray[3].concat(timeArray[4]);
     var minutesValue = timeArray[0].concat(timeArray[1]);

     var hundreths = hundrethsValue;
     var seconds = secondsValue;
     var minutes = minutesValue;    

document.getElementById("time").innerHTML = minutes + ":" + seconds + ":" + hundreths;

}

GLOBAL SCOPE (FUNCTION DOES NOT RUN) http://jsbin.com/fuxexajozu/2/edit 全球范围(功能未运行) http://jsbin.com/fuxexajozu/2/edit

var userTime = timeInput.value;
var timeString = userTime.toString();
var timeArray = timeString.split("");
var hundrethsValue = timeArray[6].concat( timeArray[7]);
var secondsValue = timeArray[3].concat(timeArray[4]);
var minutesValue = timeArray[0].concat(timeArray[1]);

var hundreths = hundrethsValue;
var seconds = secondsValue;
var minutes = minutesValue;  


function addTime() {

document.getElementById("time").innerHTML = minutes + ":" + seconds + ":" + hundreths;

}

PASSING VARIABLES TO FUNCTION (GLOBAL SCOPE) - (FUNCTION DOES NOT RUN) 通过功能变量(全局范围)-(功能未运行)

var userTime = timeInput.value;
var timeString = userTime.toString();
var timeArray = timeString.split("");
var hundrethsValue = timeArray[6].concat( timeArray[7]);
var secondsValue = timeArray[3].concat(timeArray[4]);
var minutesValue = timeArray[0].concat(timeArray[1]);

var hundreths = hundrethsValue;
var seconds = secondsValue;
var minutes = minutesValue;  


function addTime(minutes, seconds, hundreths) {


document.getElementById("time").innerHTML = minutes + ":" + seconds + ":" + hundreths;

}

*note: the running function only runs in jsbin, not jsfiddle *注意:正在运行的函数仅在jsbin中运行,而不在jsfiddle中运行

I can't identify why the the variables only run with a local scope. 我无法确定为什么变量仅在本地范围内运行。 I would like them to run with global scope so that I can use them in multiple functions. 我希望它们在全局范围内运行,以便可以在多种功能中使用它们。 Please provide any input. 请提供任何输入。 I am new to this so my knowledge of scopes is limited. 我对此并不陌生,因此我对范围的了解有限。

HTML (if needed) HTML(如果需要)

<input id="timeInput" name="timeInput" type="text " length="20">

<h1><div id="time">00:00:00</div></h1>

<div id="result"></div>

<button onclick=addTime(); >Submit</button>

<button id="start" onclick = startClock();>Start</button>

<button id="stop" onclick="stopTimer();">Stop</button>

<button id="clear" onclick="resetTimer();">Reset</button>

I suppose that 我想

LOCAL SCOPE (FUNCTION RUNS) 局部范围(功能运行)

All values are being got on click so every local variable has actual values. 所有值都可以单击,因此每个局部变量都具有实际值。

GLOBAL SCOPE 全球范围

All variables are defined on page load and have empty values. 所有变量都在页面加载时定义,并且具有空值。 These variables stay the same the whole page life. 这些变量在整个页面寿命中保持不变。 And each click on Submit reads the same (old) values every timeю 每次单击“提交”时,每次都会读取相同的(旧)值。

Anyway avoid using global variables. 无论如何,避免使用全局变量。 They will make your life worse in future. 它们会使您的生活变得更糟。

In your case I cannot see the reason to use these global variables at all because they should have actual values on button click. 在您的情况下,我根本看不到使用这些全局变量的原因,因为在单击按钮时它们应该具有实际值。

So as @Alnitak suggested it's much better to move event handler definitions from HTML page to JS files and use local variables: 因此,正如@Alnitak所建议的,将事件处理程序定义从HTML页面移动到JS文件并使用局部变量要好得多:

document.getElementById("mySubmitButton").onclick = function addTime() {
     var userTime = timeInput.value;
     var timeString = userTime.toString();
     ...
     document.getElementById("time").innerHTML = minutes + ":" + seconds + ":" + hundreths;
}

Two issues: 两个问题:


Variable value: is userTime really what you expect it to be? 可变值: userTime真的是您期望的吗?

The first issue is that you read off the input value as soon as the page loads and the input field is empty, of course. 第一个问题是,您当然会在页面加载且输入字段为空时立即读取输入值。 You always need to have most up-to-date value there, so you should definitely read the input when the addTime function is called. 您始终需要那里有最新的值,因此,一定要在addTime函数时读取输入。

If you wish, you can still keep variables global, but you have to read the input when needed. 如果愿意,仍可以使变量保持全局,但是必须在需要时读取输入。


Accessing element values - risky business! 访问元素值-冒险的生意!

The second issue will explain why your code works in some online environments and not in others and is something you should generally avoid. 第二个问题将解释为什么您的代码在某些联机环境中而不在其他联机环境中有效,这是您通常应避免的事情。 It's this line: 是这行:

var userTime = timeInput.value;

This part: timeInput.value depends on the browser and the scope context. 这部分: timeInput.value取决于浏览器和范围上下文。 By the browser I mean each browser's JS implementation - most of them will work as expected and pack names elements as scope context properties (unless they're taken, of course). 对于浏览器,我指的是每个浏览器的JS实现-大多数将按预期运行,并将名称元素打包为作用域上下文属性(当然,除非采用它们)。 Usually, that's the window object, but it doesn't have to be. 通常,这是window对象,但不一定必须如此。 Always do something like this instead: 请始终执行以下操作:

var userTime = document.getElementById('timeInput').value;

There are some nice answers about this specific issue here: Do DOM tree elements with ids become global variables? 关于此特定问题,这里有一些不错的答案: 具有ID的DOM树元素是否会成为全局变量? .


Another thing to watch out for is quoting HTML element attribute values. 要注意的另一件事是引用HTML元素属性值。 Here, for example: 例如,在这里:

<button onclick=addTime(); >

Always quote the values, because you might encounter weird issues if you don't (if there are spaces, etc.), and it might be hard to debug. 始终引用这些值,因为如果不这样做,可能会遇到奇怪的问题(如果有空格等),并且可能很难调试。 So, the right way would be: 因此,正确的方法是:

<button onclick="addTime();" >

Or even better, you'd assign the click listener from the JS, and not in the HTML markup, using addEventListener , like this: 甚至更好的是,您可以使用addEventListener从JS(而不是HTML标记)中分配JS的点击监听器,如下所示:

<button id="timeButton">

var timeButton = document.getElementById('timeButton');
timeButton.addEventListener('click', addTime);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM