javascript 函数未定义,但我的脚本正在加载

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31140712/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 13:21:20  来源:igfitidea点击:

javascript function is undefined but my script is being loaded

javascript

提问by Raiding_rider

So I'm trying to master JavaScript and to practice I'm trying to make a reaction time test. The idea is very simple: you click on a button and after a random period of time the background changes colour and then you have to click on a second button which calls on a function that calculates your reaction time. Here is my JavaScript code:

所以我正在尝试掌握 JavaScript 并练习我正在尝试进行反应时间测试。这个想法很简单:你点击一个按钮,在随机的一段时间后背景改变颜色,然后你必须点击第二个按钮,该按钮调用一个计算你的反应时间的函数。这是我的 JavaScript 代码:

function start(){
    console.log(start);
    var rndnr = (Math.round(Math.floor(Math.random() * 5) + 1)) * 1000);
    setTimeout(function timeout() {
      document.bgColor="ffff00";
      start = new Date();
    }, rndnr);
}

function stop() {
    var onclick = new Date();
    var time = onclick-start;
    var total;
    var avg;
    var count = 1;
    document.getElementById("try 1").innerHTML = time;
    total = total + time;
    avg = total / count;
    count = count + 1;
    document.getElementById("avg1").innerHTML = avg;
}

and these are my buttons:

这些是我的按钮:

<button id="button" onclick="start()" >start</button>
<button onclick="stop()">stop</button>

When I try to execute the script I get an error in my console log which says this: ReferenceError: start is not defined. Where have I gone wrong?

当我尝试执行脚本我得到了我的控制台日志中的错误,这样说:ReferenceError: start is not defined。我哪里错了?

回答by Sebastian Nette

To ensure that the document knows about the startfunction, do something like:

要确保文档知道该start函数,请执行以下操作:

window.start = function start(){ ... };

Or make sure to load your script before the handlers are assigned.

或者确保在分配处理程序之前加载脚本。

Secondly, don't try to set a value to start, since start refers to a function. Use startTimeor another variable instead.

其次,不要尝试设置一个值来启动,因为 start 指的是一个函数。改用startTime或 其他变量。

startTime = new Date();

回答by Jason Cust

You have quite a few typos in your code as well as some naming collisions and scope issues. This is your original code (aside from renaming stopto stopFsince stopis a global functionin a browser.

您的代码中有不少拼写错误以及一些命名冲突和范围问题。这是您的原始代码(除了重命名stop为,stopF因为它stop浏览器中的全局函数

function start() {
  console.log(start);
  // THE REFERENCE ERROR STEMS FROM THIS LINE PREVENTING THE FUNCTIONS
  //  FROM BEING DEFINED
  var rndnr = (Math.round(Math.floor(Math.random() * 5) + 1)) * 1000);
  setTimeout(function timeout() {
    document.bgColor = "ffff00";
    start = new Date();
  }, rndnr);
}

function stopF() {
  var onclick = new Date();
  var time = onclick - start;
  var total;
  var avg;
  var count = 1;
  document.getElementById("try 1").innerHTML = time;
  total = total + time;
  avg = total / count;
  count = count + 1;
  document.getElementById("avg1").innerHTML = avg;
}
<button id="button" onclick="start()">start</button>
<button onclick="stopF()">stop</button>
<div id="try 1"></div>
<div id="avg1"></div>

If you click "Run code snippet" you will notice an error in the console:

如果您单击“运行代码片段”,您会在控制台中注意到一个错误:

 Uncaught SyntaxError: Unexpected token )

Because of this error, neither startnor stopFare defined. Therefore when the start button is clicked the inline JS would be evaluated and then attempt to find a non-existent startfunction resulting in a ReferenceError. Similarly if the stop button is clicked it will also log a ReferenceErrorfor stopF.

由于此错误,既未定义startstopF未定义。因此,当单击开始按钮时,内联 JS 将被评估,然后尝试找到一个不存在的start函数,导致ReferenceError. 同样,如果单击停止按钮,它也会记录一个ReferenceErrorfor stopF

Correcting some of the issues in the code gives:

更正代码中的一些问题给出:

// You need to have a way of referencing the `start` variable (now `startTime`)
//  between the `start` and `stop` functions.
// You also need to be able to keep state for `total` and `count` between
//  subsequent calls to `stop`
// These issues can be solved by using scope variables
//  (here they are in the IIFE scope of the wrapper function)
var startTime;
var total = 0;
var count = 0;

// You had a name collision here within the scope of `start`
//  you also had attempted to use a variable named `start`
// Now the variable is called `startTime`
function start() {
  // You had an extra ')' in your expression assignment for `rndnr`
  var rndnr = (Math.round(Math.floor(Math.random() * 5) + 1) * 1000);
  setTimeout(function timeout() {
    document.bgColor = "ffff00";
    startTime = new Date();
    // Since setTimeout is an async function console.log would be undefined
    //  until this function runs
    console.log(startTime);
  }, rndnr);
}

function stop() {
  var onclick = new Date();
  var time = onclick - startTime;
  var avg;
  total += time;
  avg = total / ++count;

  // You shouldn't include spaces in ID values as it can be confusing
  //  if this was intentional
  document.getElementById("try1").innerHTML = time;
  document.getElementById("avg1").innerHTML = avg;
  document.bgColor = "ffffff";
}
<button id="button" onclick="start()">start</button>
<button onclick="stop()">stop</button>
<div id="try1"></div>
<div id="avg1"></div>

回答by Ben Zhong

var rndnr = (Math.round(Math.floor(Math.random()*5)+1))*1000);

syntax error,it should be

语法错误,应该是

var rndnr = (Math.round(Math.floor(Math.random()*5)+1))*1000;

回答by HolloW

Edited:

编辑:

Here is a working version of your code (only the stop button needs the tags "try 1" and "avg")

这是您的代码的工作版本(只有停止按钮需要标签“try 1”和“avg”)

http://jsfiddle.net/2q84yvzu/

http://jsfiddle.net/2q84yvzu/

The problem was on the extra ) on:

问题出在额外的 ) 上:

var rndnr = (Math.round(Math.floor(Math.random()*5)+1))*1000);

This is the correct version:

这是正确的版本:

var rndnr = (Math.round(Math.floor(Math.random()*5)+1))*1000;

I changed the way of you bind the events to the elements, is not a good practice to embed the events inline. Instead try the next approach:

我改变了你将事件绑定到元素的方式,内联嵌入事件不是一个好习惯。而是尝试下一种方法:

document.getElementById('start').onclick=function(){start();};
document.getElementById('stop').onclick=function(){stop();};

For more info on this, here is another question:

有关这方面的更多信息,这里是另一个问题:

Inline onclick JavaScript variable

内联 onclick JavaScript 变量

回答by Vladimir

You need to rename variable startinside setTimeout function, because you override function start with date value after the first call of start()function.

您需要start在 setTimeout 函数内重命名变量,因为您在第一次调用start()函数后以日期值覆盖函数开始。

function f(){
    setTimeout(function(){ f = 1; }, 1000);
}

console.log(f); // function

f();

setTimeout(function(){ 
  console.log(f); // 1
}, 1100);

回答by Kbi

console.log(start); 

is wrong

是错的

It has to be

它一定要是

console.log("start"); 

or you have to create the variable start

或者你必须创建变量 start

var start = "put anything in here";
console.log(start);