我有此代码要求在td中显示一个数字。但是它不能正常工作。
用户只能输入在func1中传递的最小值和最大值之间的值。并且该数字必须是有效数字。
如果满足这些条件,则td应该显示用户输入的号码,否则应再次出现提示用户输入有效数字的提示。
如果用户首先输入一个有效数字,则该代码有效,例如,在这种情况下,最小值为1,最大值为10,如果用户在这两个值之间输入数字,则该代码有效用户出现在td上。但是,如果用户输入数字0,则会出现消息“值0无效”,并再次出现提示,这是正确的。但是,如果用户输入的有效数字(例如1),则在td中显示为未定义,而不是1。
你知道为什么吗?
HTML
<tr>
<td>Number</td>
<td id="tdNumber"></td>
<td>
<button onclick="func1()">Add</button>
</td>
</tr>
JS
let config = {
numberX: NUMBER_X
}
function showConfig() {
document.getElementById(TD_NUMBER).innerHTML = config.numberX;
}
function func1() {
config.numberX = func2(1, 10, P_CONSTANT);
showConfig();
}
function func2(min, max, p = P_CONSTANT) {
var number = parseInt(prompt("Enter a number between " + min + "and " + max));
if (!Number.isInteger(number)) {
alert("The number " + number + " is not valid.");
func1();
} else if (number > max || number < min) {
alert("The number " + number + " is not valid");
func1();
} else {
return number;
}
}
答案 0 :(得分:0)
程序的结构是真正的问题。可能可以使它起作用,但这不是实现它的方法。取而代之的是让func2()
返回一些表示无效数字的值,然后在func1()
内进行迭代:
const INVALID = {};
function func1() {
let p;
for (p = func2(1, 10); p === INVALID; p = func2(1, 10)) {
alert("Invalid value");
}
config.numberX = p;
showConfig();
}
function func2(min, max, p = P_CONSTANT) {
var number = parseInt(prompt("Enter a number between " + min + "and " + max));
if(!Number.isInteger(number)){
return INVALID;
}
if(number > max || number < min){
return INVALID;
}
return number;
}
答案 1 :(得分:0)
您编写func1
和func2
的方式,他们可以无限制地互相呼叫。想象一下这种情况:
func1()
被称为(称为func1_A
)func1_A
呼叫func2()
以获取号码(这是func2_B
)func2_B
发起了另一个呼叫func1
(func1_C
)func1_C
调用func2()
以获取新号码(func2_D
)func2_D
返回有效数字,func1_C
将其分配给numberX
func1_C
返回,执行返回到一直在等待的func2_B
,func2_B
无事可做,因此返回undefined
func1_A
从undefined
获取func2_B
并将其分配给numberX
基本上,您拥有这些互相调用的功能的事实将继续向堆栈中添加 new 调用,而 old 调用必须等待这些调用才能返回。而且重要的是,旧的将恢复-这意味着最后发生的事情将始终是func1
分配func2
的最新返回值,如果用户 ever 输入了该值无效的数字将是undefined
。
Pointy是对的:这是一种非常差的格式,容易出现很多问题。这不是您应该追求的方法。至少,您的代码不应因不必要的递归函数调用而不必要地容易出现堆栈溢出错误。
您可以使用while
循环将其简化很多。我也是有意义名称的忠实拥护者,func1
/ func2
与有意义的名称相距甚远,因此我已将函数重命名。
const NUMBER_X = 10;
const P_CONSTANT = "???";
const TD_NUMBER = "tdNumber";
let config = {
numberX: NUMBER_X
};
function showConfig() {
console.log(document.getElementById(TD_NUMBER));
document.getElementById(TD_NUMBER).innerHTML = config.numberX;
}
function setNumber() {
config.numberX = getValidNumber(1, 10, P_CONSTANT);
showConfig();
}
function getValidNumber(min, max, p = P_CONSTANT) {
var isValid = false;
var number;
do {
number = parseInt(prompt("Enter a number between " + min + " and " + max));
if(!Number.isInteger(number)) {
alert("The number " + number + " is not valid.");
} else if(number > max || number < min) {
alert("The number " + number + " is not valid");
} else {
isValid = true;
}
} while(!isValid);
return number;
}
<table>
<tr>
<td>Number</td>
<td id="tdNumber"></td>
<td><button onclick="setNumber()">Add</button></td>
</tr>
</table>
答案 2 :(得分:0)
func1
呼叫func2
时,
func1
等待响应。
如果输入错误,func1
就不会得到答案,因为func2
再次调用func1
...
这总共使 2 func1
个功能都等待响应,
如果新输入的内容有误,则将使它成为第三个;
只有这个堆栈上的最后一个会得到回报,
而所有其他func1
将继续徒劳地等待
正确的编码方式是:
const tdNumber = document.getElementById('td-number')
, NUMBER_X = 10
, minVal = 1
, maxVal = 10
, config = { numberX: NUMBER_X }
;
function setNumber()
{
let numberStr = ''
, numberIn = 0
, badEntry = true
;
do
{
numberStr = prompt( "Enter a number between " + minVal + "and " + maxVal )
numberIn = parseFloat( numberStr )
badEntry = ( !Number.isInteger( numberIn ))
|| numberIn < minVal
|| numberIn > maxVal
;
if ( badEntry )
{ alert("The number " + numberStr + " is not valid") }
}
while ( badEntry )
tdNumber.textContent = config.numberX = numberIn
}
table {
border-collapse: collapse;
margin: 1em;
}
td {
border: solid grey 1px;
padding: 1em;
text-align : center;
}
#td-number {
width : 4em
}
<table>
<tr>
<td>Number</td>
<td id="td-number"></td>
<td><button onclick="setNumber()">Add</button></td>
</tr>
</table>