JavaScript中的函数一旦被触发就不起作用了吗?

5

我正在从头开始开发一个纯JavaScript计算器。我已经成功地将数字和运算符分离,但是当我将数组传递给另一个函数时,该函数出现无法工作的问题。请注意,我是一个自学者,也是初学者JavaScript开发人员,所以我正在学习和实践。以下是代码:

//Index.js where the problem is
// this the field to control the result textfield
var textfield = " ";

//this function to copy the number/operations button to the textfiled
//it works
function retunNumber(val) {
    console.log(val);
    if (textfield != " ") {
        textfield = textfield + val;
        document.getElementById('result').value = textfield;
    } else if (textfield == " ") {
        textfield = val;
        document.getElementById('result').value = textfield;
    }
}

//this function to clear the textfield
//it works
document.getElementById('clear').addEventListener("click", function(){
    document.getElementById('result').value= " ";
    textfield = " ";
});



// This the functions where the calculation spouses to //happen but 
//nothing
//not sure
function result(numbers, operations){

    var currentResult = numbers[0];
    for(var i =0; i<= operations.length ; i++){
        if(operations[i] == '+'){
            currentResult = currentResult + numbers[i+1];
        }else if(operations[i] == '-'){
            currentResult = currentResult - numbers[i+1];
        }else if(operations[i] == '*'){
            currentResult = currentResult * numbers[i+1];
        }if(operations[i] == '/'){
            currentResult = currentResult / numbers[i+1];
        }else{
            currentResult = "Wrong";
        } 
    }return currentResult;
}

//this the function where it should give the result
// it works partially, only in the separation of the number and the 
//operation but not in returning the result
document.getElementById('equal').addEventListener("click", function(){

    var numbers = textfield.split(/\D/g);
    var operations = textfield.split(/\d/g).filter(Boolean);
    
    /*
    console.log(textfield);
    console.log(numbers);
    console.log(operations);
    */
//here is where it spouses to return the result but nothing
   if(Number.isInteger(result(numbers, operations)) == true){
    textfield =result(numbers, operations);
   }else{
       textfield = "Invalid expression"
   }
    


});
.grid-container {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-gap: 10px;
}

.container {
    margin: 10%;

}

.item1 {
grid-column: 1/5;
}

.item2 {
    grid-column: 2/4;
}

.item3 {
    grid-row: 2;
    grid-column: 4;
}

.item4 {
    grid-row: 3;
    grid-column: 4;
}
.item5 {
    grid-row: 4;
    grid-column: 4;
}

.textField {
    width: 100%;
}
<html>

<head>
    <title>Calculator</title>

    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
        integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

</head>

<body>
    <div class="container">

        <div class="grid-container">

            <div class="item1"> <input type="text" name="result" id="result" class="textField"> </div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="1">1</button> </div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="2">2</button> </div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="3">3</button></div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="4">4</button></div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="5">5</button></div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="6">6</button></div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="7">7</button></div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="8">8</button></div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="9">9</button></div>
            <div class="item2"> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="0">0</button></div>
            <div class="item5"> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="*">*</button></div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="/">/</button></div>
            <div class="item3"> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="+">+</button></div>
            <div class="item4"> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="-">-</button></div>
            <div> <button class="btn btn-outline-info" id="equal">Equal</button></div>
            <div> <button class="btn btn-outline-info">Delete</button></div>
            <div> <button class="btn btn-outline-info" id="clear">Clear</button></div>


        </div>

    </div>
</body>

<script src="index.js"></script>

</html>


1
这个条件:“i<= operations.length” 应该改为 “i< operations.length”。 - ziggy wiggy
1
这个代码块:} else if (textfield == " ") { 可以简化为 } else {,因为此时你已经知道 textfied 等于 " " - ziggy wiggy
@ziggywiggy 我什么也没改,还是一样的 :( 现在我会尝试下一条评论。 - AbdallahRizk
1
这个:}if(operations[i] == '/'){ 应该改为 } else if(operations[i] == '/'){,否则下一个 else 会抹掉上面可能已经满足的任何条件。 - ziggy wiggy
1
这是我写result函数的方式(仅供参考):function result(numbers, operations) { return operations.reduce((res, op, i) => op == '+' ? res + numbers[i + 1] : op == '-' ? res - numbers[i + 1] : op == '*' ? res * numbers[i + 1] : op == '/' ? res / numbers[i + 1] : NaN, numbers[0]) } - ziggy wiggy
显示剩余3条评论
4个回答

1
有几个小问题。
  1. }if(operations[i] == '/'){ 需要改为 }else if(operations[i] == '/'){ 添加 else

  2. for(var i =0; i<= operations.length ; i++){ 需要改为 for(var i =0; i< operations.length ; i++){ 删除 =

  3. 你正在赋值给 textfield,因此当你再次点击 equal 时,textfield 不再是你认为的值。你需要将 textField 赋值为页面上的文本框。

  4. result 函数内部,currentResultnumbers[i+1] 被视为 string 类型。你需要使用 parseInt 将它们转换为整数。

  5. Number.isInteger 在这种情况下总是返回 false,因为函数 result 的返回类型是 string。你需要在函数调用前面添加 + 将其转换回数字。

   //Index.js where the problem is
var textfield = " ";

function retunNumber(val) {
    console.log(val);
    if (textfield != " ") {
        textfield = textfield + val;
        document.getElementById('result').value = textfield;
    } else if (textfield == " ") {
        textfield = val;
        document.getElementById('result').value = textfield;
    }
}

document.getElementById('clear').addEventListener("click", function(){
    document.getElementById('result').value= " ";
    textfield = " ";
});



// This the functions where the calculation spouses to //happen but nothing
function result(numbers, operations){

    var currentResult = parseInt(numbers[0]);
    for(var i =0; i < operations.length ; i++){
        if(operations[i] == '+'){
            currentResult = currentResult + parseInt(numbers[i+1]);
        }else if(operations[i] == '-'){
            currentResult = currentResult - parseInt(numbers[i+1]);
        }else if(operations[i] == '*'){
            currentResult = currentResult * parseInt(numbers[i+1]);
        }else if(operations[i] == '/'){
            currentResult = currentResult / parseInt(numbers[i+1]);
        }else{
            currentResult = "Wrong";
        } 
    }return currentResult;
}

document.getElementById('equal').addEventListener("click", function(){

    var numbers = textfield.split(/\D/g);
    var operations = textfield.split(/\d/g).filter(Boolean);
    
    /*
    console.log(textfield);
    console.log(numbers);
    console.log(operations);
    */
   if(Number.isInteger(+result(numbers, operations)) == true){
    textfield =result(numbers, operations);
   }else{
       textfield = "Invalid expression"
   }
   document.getElementById('result').value = textfield;


});
.grid-container {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-gap: 10px;
}

.container {
    margin: 10%;

}

.item1 {
grid-column: 1/5;
}

.item2 {
    grid-column: 2/4;
}

.item3 {
    grid-row: 2;
    grid-column: 4;
}

.item4 {
    grid-row: 3;
    grid-column: 4;
}
.item5 {
    grid-row: 4;
    grid-column: 4;
}

.textField {
    width: 100%;
}
<html>

<head>
    <title>Calculator</title>

    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
        integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

</head>

<body>
    <div class="container">

        <div class="grid-container">

            <div class="item1"> <input type="text" name="result" id="result" class="textField"> </div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="1">1</button> </div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="2">2</button> </div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="3">3</button></div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="4">4</button></div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="5">5</button></div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="6">6</button></div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="7">7</button></div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="8">8</button></div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="9">9</button></div>
            <div class="item2"> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="0">0</button></div>
            <div class="item5"> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="*">*</button></div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="/">/</button></div>
            <div class="item3"> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="+">+</button></div>
            <div class="item4"> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="-">-</button></div>
            <div> <button class="btn btn-outline-info" id="equal">Equal</button></div>
            <div> <button class="btn btn-outline-info">Delete</button></div>
            <div> <button class="btn btn-outline-info" id="clear">Clear</button></div>


        </div>

    </div>
</body>

<script src="index.js"></script>

</html>


1
讲解非常好,但在第四点有小问题。由于这是计算器,因此结果应返回整数。问题出在计算中。在result函数中计算时,需要将numbers [0]和numbers [i + 1]解析为Int类型。 - kamran
@AbdallahRizk,我不明白你所说的加法和除法无法工作的意思。 - S. Walker
1
@AbdallahRizk 2+3=23 这是因为你将两个字符串相加了。请使用 parseInt - R3tep
1
@S.Walker 你需要在函数调用前面添加+号将其转换回数字。 你还需要将计算出的值解析为整数。例如 currentResult = parseInt(currentResult) + parseInt(numbers[i+1]); - R3tep
@S.Walker请编辑您的答案,以便每个人都能受益。 - AbdallahRizk
显示剩余2条评论

1
你正在为textfield分配一个值,但这只是一个字符串,它不会自动出现在页面上。
如果你想让它的值出现在页面上(当按下“等于”时),那么你应该使用:
document.getElementById('result').value = "some value";

请注意,您还调用了两次函数result(numbers, operations),最好只调用一次并存储结果。

1

另一种方法是使用eval()函数。

你可以像这样改变你的事件相等

document.getElementById('equal').addEventListener("click", function(){
    var elResult = document.getElementById('result');
    textfield = " ";
    elResult.value = eval(elResult.value);
})

或者(更好的选择)你可以使用window.Function

document.getElementById('equal').addEventListener("click", function(){
  var elResult = document.getElementById('result');

  textfield = " ";
  elResult.value = Function('"use strict";return (' + elResult.value + ')')();
})

例如

var newNum = true;

function retunNumber(val) {
  if (newNum) {
    document.getElementById('result').value = val;
    newNum = false
  } else {
    document.getElementById('result').value += val;
  }
}

document.getElementById('clear').addEventListener("click", function() {
  document.getElementById('result').value = " ";
  newNum = true;
});

document.getElementById('equal').addEventListener("click", function() {
  var elResult = document.getElementById('result');

  newNum = true;
  elResult.value = Function('"use strict";return (' + elResult.value + ')')();
})
.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-gap: 10px;
}

.container {
  margin: 10%;
}

.item1 {
  grid-column: 1/5;
}

.item2 {
  grid-column: 2/4;
}

.item3 {
  grid-row: 2;
  grid-column: 4;
}

.item4 {
  grid-row: 3;
  grid-column: 4;
}

.item5 {
  grid-row: 4;
  grid-column: 4;
}

.textField {
  width: 100%;
}
<html>

<head>
  <title>Calculator</title>

  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="style.css">
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

</head>

<body>
  <div class="container">

    <div class="grid-container">

      <div class="item1"> <input type="text" name="result" id="result" class="textField"> </div>
      <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="1">1</button> </div>
      <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="2">2</button> </div>
      <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="3">3</button></div>
      <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="4">4</button></div>
      <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="5">5</button></div>
      <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="6">6</button></div>
      <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="7">7</button></div>
      <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="8">8</button></div>
      <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="9">9</button></div>
      <div class="item2"> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="0">0</button></div>
      <div class="item5"> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="*">*</button></div>
      <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="/">/</button></div>
      <div class="item3"> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="+">+</button></div>
      <div class="item4"> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="-">-</button></div>
      <div> <button class="btn btn-outline-info" id="equal">Equal</button></div>
      <div> <button class="btn btn-outline-info">Delete</button></div>
      <div> <button class="btn btn-outline-info" id="clear">Clear</button></div>


    </div>

  </div>
</body>

<script src="index.js"></script>

</html>


你的解决方案很有创意,但它让我以另一种方式去解决问题。我真的想知道我的当前方法有什么问题,但肯定我会去了解eval()和windows.function,因为现在我只看到了魔法。 - AbdallahRizk

0

值的数组是一个字符串数组,因此您必须将每个项目转换为数字,使用parseInt

/* here must be `else if` */

} if(operations[i] == '/'){ 
        currentResult = currentResult / numbers[i+1];
    }else{
        currentResult = "Wrong";
    } 

注意:浮点数可能会出现错误。优先级被忽略。

//Index.js where the problem is
// this the field to control the result textfield
var textfield = " ";

//this function to copy the number/operations button to the textfiled
//it works
function retunNumber(val) {
    if (textfield != " ") {
        textfield = textfield + val;
        document.getElementById('result').value = textfield;
    } else if (textfield == " ") {
        textfield = val;
        document.getElementById('result').value = textfield;
    }
}

//this function to clear the textfield
//it works
document.getElementById('clear').addEventListener("click", function(){
    document.getElementById('result').value= " ";
    textfield = " ";
});



// This the functions where the calculation spouses to //happen but 
function result(numbers, operations){
    
    var currentResult = parseInt(numbers[0]); // first of all, convert to number
    
    for(var i = 0; i < operations.length ; i++) {
        // convert to number
        var currentNumber = parseInt(numbers[i+1]);
        
        if(operations[i] == '+') {
            currentResult +=  currentNumber
        } else if(operations[i] == '-') {
            currentResult -=  currentNumber
        } else if(operations[i] == '*') {
            currentResult *=  currentNumber
        } else if(operations[i] == '/') {
            currentResult /=  currentNumber
        } else {
            currentResult = "Wrong";
        }
    }
    return currentResult;
}

//this the function where it should give the result
// it works partially, only in the separation of the number and the 
//operation but not in returning the result
document.getElementById('equal').addEventListener("click", function(){

   var numbers = textfield.split(/\D/g);
   var operations = textfield.split(/\d/g).filter(Boolean);
    
   const res = result(numbers, operations)
   if( Number.isInteger(res) ) { /* == true <- redundant  ){ */
       textfield = res;
   } else {
       textfield = "Invalid expression"
   }

    /* set value to texfield */
    document.getElementById('result').value = textfield;

});
.grid-container {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-gap: 10px;
}

.container {
    margin: 10%;

}

.item1 {
grid-column: 1/5;
}

.item2 {
    grid-column: 2/4;
}

.item3 {
    grid-row: 2;
    grid-column: 4;
}

.item4 {
    grid-row: 3;
    grid-column: 4;
}
.item5 {
    grid-row: 4;
    grid-column: 4;
}

.textField {
    width: 100%;
}
<html>

<head>
    <title>Calculator</title>

    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
        integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

</head>

<body>
    <div class="container">

        <div class="grid-container">

            <div class="item1"> <input type="text" name="result" id="result" class="textField"> </div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="1">1</button> </div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="2">2</button> </div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="3">3</button></div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="4">4</button></div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="5">5</button></div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="6">6</button></div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="7">7</button></div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="8">8</button></div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="9">9</button></div>
            <div class="item2"> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="0">0</button></div>
            <div class="item5"> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="*">*</button></div>
            <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="/">/</button></div>
            <div class="item3"> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="+">+</button></div>
            <div class="item4"> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="-">-</button></div>
            <div> <button class="btn btn-outline-info" id="equal">Equal</button></div>
            <div> <button class="btn btn-outline-info">Delete</button></div>
            <div> <button class="btn btn-outline-info" id="clear">Clear</button></div>


        </div>

    </div>
</body>

<script src="index.js"></script>

</html>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接