2017-12-31 232 views
-1

자바 스크립트를 사용하여 계산기를 만들었습니다. 여러 수학 문제를 연결하면 = 버튼으로 최종 결과를 얻을 때까지 원하는 답을 얻을 수 있습니다. 두 개의 숫자 만 할 때 = 버튼은 완벽하게 작동합니다. 내 코드를 mathHoldOne 및 mathHoldTwo로 설정하도록 설정했습니다. 둘 다 숫자와 부울 값을 포함하거나 포함하지 않습니다. dev 도구를 사용하여 두 숫자의 문제점과 2+ 숫자의 문제점 사이의 차이점을 확인했으며 문제점을 찾을 수없는 것으로 나타났습니다. 이 질문에 대한 하나의 답을 제공하지 않을 수도 있지만자바 스크립트 계산기 동등 함수 실패

const view = { 
    //Updates view when buttons are clicked 
    updateView: function() { 
     let viewScreen = document.getElementsByClassName('js-view')[0]; 
     let miniView = document.getElementsByClassName('mini-view')[0]; 
     viewScreen.innerHTML = ''; 
     miniView.innerHTML = ''; 
     const jsContainer = document.getElementsByClassName('js-container')[0]; 
     jsContainer.addEventListener('click', function (e) { 
      let show = e.target.innerHTML; 
      viewScreen.innerHTML += show; 
     }); 
    }, 
    //have a handler that sets what each button does with event delegation 
    btnHandle: function() { 
     let mathType = {"type": undefined}; 
     let mathHoldOne = {"num": 0, "set": false}; 
     let mathHoldTwo = {"num": 0, "set": false}; 
     let btnHandler = document.querySelector('.js-container'); 

     btnHandler.addEventListener('click', function (event) { 
      let btn = event.target; 
      let screenValue = document.querySelector('.js-view'); 
      let miniView = document.querySelector('.mini-view'); 
      switch (btn.className) { 
       //clears whats in the view window 
       case('cell clear'): 
        screenValue.innerHTML = ''; 
        miniView.innerHTML = ''; 
        mathHoldOne.num = 0; 
        mathHoldOne.set = false; 
        mathHoldTwo.num = 0; 
        mathHoldTwo.set = false; 
        mathType.type = undefined; 
        break; 
       case('cell math multiply'): 
        //assigns mathHoldTwo.num if mathHoldOne.set is true and blanks the screenValue 
        if (mathHoldOne.set) { 
         mathHoldTwo.num = parseInt(screenValue.innerHTML); 
         mathHoldTwo.set = true; 
         screenValue.innerHTML = ''; 
         //if mathHoldOne.set is false it assigns mathHoldOne.num and sets the set property to true 
         //also sets mathType.type to multiply 
        } else { 
         mathHoldOne.num = parseInt(screenValue.innerHTML); 
         mathHoldOne.set = true; 
         screenValue.innerHTML = ''; 
         mathType.type = "mulitply"; 
        } 
        if (mathHoldOne.set && mathHoldTwo.set) { 
         //if both numbers are set cycle through calcFunc to find which mathType.type matches 
         //and execute that function with the two values 
         for (let name in calcFunc) { 
          if (mathType.type === name) { 
           miniView.innerHTML = calcFunc[name](mathHoldOne.num, mathHoldTwo.num); 
           mathHoldOne.num = calcFunc[name](mathHoldOne.num, mathHoldTwo.num); 
          } 
         } 
         mathHoldTwo.num = 0; 
         mathHoldTwo.set = false; 
         mathType.type = 'multiply'; 
        } 
        break; 
       case('cell math divide'): 
        if (mathHoldOne.set) { 
         mathHoldTwo.num = parseInt(screenValue.innerHTML); 
         mathHoldTwo.set = true; 
         screenValue.innerHTML = ''; 
        } else { 
         mathHoldOne.num = parseInt(screenValue.innerHTML); 
         mathHoldOne.set = true; 
         screenValue.innerHTML = ''; 
         mathType.type = "divide"; 
        } 
        if (mathHoldOne.set && mathHoldTwo.set) { 
         for (let name in calcFunc) { 
          if (mathType.type === name) { 
           miniView.innerHTML = calcFunc[name](mathHoldOne.num, mathHoldTwo.num); 
           mathHoldOne.num = calcFunc[name](mathHoldOne.num, mathHoldTwo.num); 
          } 
         } 
         mathHoldTwo.num = 0; 
         mathHoldTwo.set = false; 
         mathType.type = 'divide'; 
        } 
        break; 
       case('cell math add'): 
        if (mathHoldOne.set) { 
         mathHoldTwo.num = parseInt(screenValue.innerHTML); 
         mathHoldTwo.set = true; 
         screenValue.innerHTML = ''; 
        } else { 
         mathHoldOne.num = parseInt(screenValue.innerHTML); 
         mathHoldOne.set = true; 
         screenValue.innerHTML = ''; 
         mathType.type = "add"; 
        } 
        if (mathHoldOne.set && mathHoldTwo.set) { 
         for (let name in calcFunc) { 
          if (mathType.type === name) { 
           miniView.innerHTML = calcFunc[name](mathHoldOne.num, mathHoldTwo.num); 
           mathHoldOne.num = calcFunc[name](mathHoldOne.num, mathHoldTwo.num); 
          } 
         } 
         ; 
         mathHoldTwo.num = 0; 
         mathHoldTwo.set = false; 
         mathType.type = 'add'; 
        } 
        break; 
       case('cell math subtract'): 
        if (mathHoldOne.set) { 
         mathHoldTwo.num = parseInt(screenValue.innerHTML); 
         mathHoldTwo.set = true; 
         screenValue.innerHTML = ''; 
        } else { 
         mathHoldOne.num = parseInt(screenValue.innerHTML); 
         mathHoldOne.set = true; 
         screenValue.innerHTML = ''; 
         mathType.type = "subract"; 
        } 
        if (mathHoldOne.set && mathHoldTwo.set) { 
         for (let name in calcFunc) { 
          if (mathType.type === name) { 
           miniView.innerHTML = calcFunc[name](mathHoldOne.num, mathHoldTwo.num); 
           mathHoldOne.num = calcFunc[name](mathHoldOne.num, mathHoldTwo.num); 
          } 
         } 
         ; 
         mathHoldTwo.num = 0; 
         mathHoldTwo.set = false; 
         mathType.type = 'subtract'; 
        } 
        break; 
       case('cell equal'): 
        mathHoldTwo.num = parseInt(screenValue.innerHTML); 
        if (mathType.type === "add") { 
         screenValue.innerHTML = calcFunc.add(mathHoldOne.num, mathHoldTwo.num); 
         miniView.innerHTML = calcFunc.add(mathHoldOne.num, mathHoldTwo.num); 
         mathHoldTwo.num = 0; 
         mathHoldOne.num = 0; 
         mathHoldOne.set = false; 
        } else if (mathType.type === "subract") { 
         screenValue.innerHTML = calcFunc.subtract(mathHoldOne.num, mathHoldTwo.num); 
         miniView.innerHTML = calcFunc.subtract(mathHoldOne.num, mathHoldTwo.num); 
         mathHoldOne.num = (mathHoldOne.num - mathHoldTwo.num); 
         mathHoldTwo.num = 0; 
         mathHoldOne.num = 0; 
         mathHoldOne.set = false; 
        } 
        else if (mathType.type === "mulitply") { 
         screenValue.innerHTML = calcFunc.multiply(mathHoldOne.num, mathHoldTwo.num); 
         miniView.innerHTML = calcFunc.multiply(mathHoldOne.num, mathHoldTwo.num); 
         mathHoldOne.num = (mathHoldOne.num * mathHoldTwo.num); 
         mathHoldTwo.num = 0; 
         mathHoldOne.num = 0; 
         mathHoldOne.set = false; 
        } else if (mathType.type === "divide") { 
         screenValue.innerHTML = calcFunc.divide(mathHoldOne.num, mathHoldTwo.num); 
         miniView.innerHTML = calcFunc.divide(mathHoldOne.num, mathHoldTwo.num); 
         mathHoldOne.num = (mathHoldOne.num/mathHoldTwo.num); 
         mathHoldTwo.num = 0; 
         mathHoldOne.num = 0; 
         mathHoldOne.set = false; 
        } 
        break; 
      } 
      console.log(mathHoldOne, mathHoldTwo, mathType.type); 
     }) 
    } 

}; 

view.updateView(); 
view.btnHandle(); 
const calcFunc = { 
    add: function (x, y) { 
     return x + y; 
    }, 
    subtract: function (x, y) { 
     return x - y; 
    }, 
    multiply: function (x, y) { 
     return x * y; 
    }, 
    divide: function (x, y) { 
     return x/y; 
    }, 
    clear: function() { 
     let view = document.querySelector('js-view'); 
     view.innerHTML = ''; 
    } 
} 
+1

적 기본 계산 문제에 대한'eval' 또는'새 Function'를 사용하여 생각? 나는 당신이 multiply 함수에 대해서도 문제가 있다고 생각한다. (case ('cell equal')'statement ifs 블록에 쓰여진 것 같다.) 나는 또한 당신의 코드가 지나치게 복잡하다고 믿는다. (예를 들어, 모든 경우에이 호출은'if (mathHoldOne.set && mathHoldTwo.set)'이지만, 당신은 그것을 다소 동적으로 평가한다. 나머지는' 5 + 3 * 5'는'20'이며, 문장을 한 번에 실행하면 코드가'40'으로 평가할 것입니다. – Icepickle

답변

0

codepen, 나는 내가 계산기의 다른 버전을 제공 할 수 있다고 생각.

여기에서 가장 중요한 점은 문자열을 (격리 된 부분의) JavaScript 코드로 실행할 수있는 new Function 문을 통해 계산이 해제된다는 것입니다.

버튼을 클릭하면 계산이 완료됩니다. 거짓 문장으로주는 것을 배제하지 않으므로 코드는 try/catch 블록에 저장됩니다. catch 블록에서 당신은 그냥 오류를 기록하고 0

function executeCalculation(calculation) { 
    var fn = new Function(`return (${calculation});`); 
    try { 
    return fn(); 
    } catch (ex) { 
    console.log(ex); 
    return 0; 
    } 
} 

에게 전체 계산을 한 번에 평가입니다 도착 사실을 반환 현재 버전에서, 그가 입력 한 계산이 올바르지 사용자에게 나타낼 수 이점은 다음과 같이 order of operators이 예상대로 보존됩니다. 이 주문의 예는 내가 의견에 남긴 것으로서 5 + 3 * 5을 계산하려고하면 20이되어야하지만 현재 계산에서는 5 + 3 = 8 * 5 = 40으로 계산됩니다.

// attach basic event handlers 
 
document 
 
    .querySelectorAll('button') 
 
    .forEach( 
 
    button => button.addEventListener('click', updateCalculation) 
 
); 
 
    
 
// some global variables 
 
let currentCalculation = ''; 
 
let currentValue = 0; 
 
let memory = 0; 
 
    
 
// event handler for clicking on the buttons 
 
function updateCalculation(e) { 
 
    let source = e.target; 
 
    if (!source) { 
 
    return; 
 
    } 
 
    // use the data-type attribute to check what action needs to be performed 
 
    let type = source.getAttribute('data-type'); 
 
    if (!type) { 
 
    return; 
 
    } 
 
    switch (type) { 
 
    case '=': 
 
     currentValue = executeCalculation(currentCalculation); 
 
     currentCalculation = ''; 
 
     break; 
 
    case 'clear-view': 
 
     currentCalculation = ''; 
 
     break; 
 
    case 'clear-all': 
 
     currentValue = 0; 
 
     currentCalculation = ''; 
 
     break; 
 
    case 'store': 
 
     memory = currentValue; 
 
     break; 
 
    case 'retrieve': 
 
     currentCalculation += memory; 
 
     break; 
 
    case 'clear': 
 
     memory = 0; 
 
     break; 
 
    case '*': 
 
    case '+': 
 
    case '-': 
 
    case '/': 
 
     // in case the currentCalculation is empty, it should start with the current value instead 
 
     if (currentCalculation === '') { 
 
     currentCalculation = currentValue; 
 
     } 
 
     currentCalculation += type; 
 
     break; 
 
    default: 
 
     currentCalculation += type; 
 
    } 
 
    // update the screen with the changes 
 
    updateView(currentValue, currentCalculation); 
 
} 
 

 
function updateView(value, calculation) { 
 
    document.querySelector('.entry').innerHTML = value; 
 
    document.querySelector('.current-query').innerHTML = calculation; 
 
} 
 

 
// executes and returns the result of the calculation 
 
function executeCalculation(calculation) { 
 
    var fn = new Function(`return (${calculation});`); 
 
    try { 
 
    return fn(); 
 
    } catch (ex) { 
 
    console.log(ex); 
 
    return 0; 
 
    } 
 
}
.calculator { 
 
    background-color: #000; 
 
    display: inline-block; 
 
} 
 
button { 
 
    margin: 3px; 
 
} 
 
.entry { 
 
    display: block; 
 
    margin: 3px; 
 
    padding: 5px; 
 
    color: #fff; 
 
    text-align: right; 
 
    border: inset #fff 1px; 
 
} 
 
.current-query { 
 
    font-size: 0.7em; 
 
    text-align: right; 
 
    color: #fff; 
 
    height: 20px; 
 
} 
 
.row { 
 
    display: flex; 
 
    flex-flow: row nowrap; 
 
} 
 
.column { 
 
    display: flex; 
 
    flex-flow: column nowrap; 
 
}
<div class="calculator"> 
 
<div class="header"> 
 
    <div class="view"> 
 
    <div class="entry">0</div> 
 
    <div class="current-query"></div> 
 
    </div> 
 
</div> 
 
<div class="quick-buttons"> 
 
    <button type="button" data-type="clear-view">CE</button> 
 
    <button type="button" data-type="clear-all">C</button> 
 
    <button type="button" data-type="store">M</button> 
 
    <button type="button" data-type="retrieve">MR</button> 
 
    <button type="button" data-type="clear">MC</button> 
 
</div> 
 
<div class="main-buttons row"> 
 
    <div class="numbers column"> 
 
    <div class="row"> 
 
     <button type="button" data-type="7">7</button> 
 
     <button type="button" data-type="8">8</button> 
 
     <button type="button" data-type="9">9</button> 
 
    </div> 
 
    <div class="row"> 
 
     <button type="button" data-type="4">4</button> 
 
     <button type="button" data-type="5">5</button> 
 
     <button type="button" data-type="6">6</button> 
 
    </div> 
 
    <div class="row"> 
 
     <button type="button" data-type="1">1</button> 
 
     <button type="button" data-type="2">2</button> 
 
     <button type="button" data-type="3">3</button> 
 
    </div> 
 
    <div class="row"> 
 
     <button type="button" data-type="0">0</button> 
 
     <button type="button" data-type=".">.</button> 
 
     <button type="button" data-type="=">=</button> 
 
    </div> 
 
    </div> 
 
    <div class="operations row"> 
 
    <div class="column"> 
 
     <button type="button" data-type="+">+</button> 
 
     <button type="button" data-type="-">-</button> 
 
     <button type="button" data-type="*">*</button> 
 
     <button type="button" data-type="/">/</button> 
 
    </div> 
 
    </div> 
 
</div> 
 
</div>