简体   繁体   中英

Uncaught TypeError: Cannot read property 'toString' of undefined --javascript

I am trying to create a calculator with javascript but I keep getting an error message of "Uncaught TypeError: Cannot read property 'toString' of undefined" on the console whenever I click on the number button. and at the same time, the number button is not displayed in strings. What am I doing wrong?

 //Javascript class Calculator { constructor(previousOperandTextElement, currentOperandTextElement) { this.previousOperandTextElement = previousOperandTextElement; this.currentOperandTextElement = currentOperandTextElement; this.clear(); } clear() { this.previousOperandElement = ''; this.currentOperandElement = ''; this.operation = undefined; } delete() { } appendNumber(number) { this.currentOperand = this.currentOperand.toString() + number.toString(); } chooseOperation(operation) { } compute() { } updateDisplay() { this.currentOperandTextElement.innerText = this.currentOperand; } } const numberButtons = document.querySelectorAll('[data-number]'); const operationButtons = document.querySelectorAll('[data-operation]'); const equalsButton = document.querySelector('[data-equals]'); const deleteButton = document.querySelector('[data-delete]'); const allClearButton = document.querySelector('[data-all-clear]'); const previousOperandTextElement = document.querySelector('[data-previous-operand]'); const currentOperandTextElement = document.querySelector('[data-current-operand]'); const calculator = new Calculator(currentOperandTextElement, previousOperandTextElement); numberButtons.forEach(button => { button.addEventListener('click', () => { calculator.appendNumber(button.innerText); calculator.updateDisplay(); }); });
 //CSS *, *::before, *::after { box-sizing: border-box; font-family: Gotham Rounded, sans-serif; font-weight: normal; } body { padding: 0; margin: 0; background: linear-gradient(to right, #722f37, #caa181); }.calculator-grid { display: grid; justify-content: center; align-content: center; min-height: 100vh; grid-template-columns: repeat(4, 100px); grid-template-rows: minmax(120px, auto) repeat(5, 100px); }.calculator-grid>button { cursor: pointer; font-size: 2rem; border: 1px solid white; outline: none; background-color: rgba(255, 255, 255, .75); }.calculator-grid>button:hover { background-color: rgba(255, 255, 255, .9); }.span-two { grid-column: span 2; }.output { grid-column: 1 / -1; background-color: rgba(51, 35, 35, 0.397); display: flex; align-items: flex-end; justify-content: space-around; flex-direction: column; padding: 10px; word-wrap: break-word; word-break: break-all; }.output.previous-operand { color: rgba(255, 255, 255, .75); font-size: 1.5rem; }.output.current-operand { color: white; font-size: 2.5rem; }
 <,-- HTML --> <.DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width". initial-scale=1.0> <meta http-equiv="X-UA-compatible" content="ie=edge"> <link href="styles.css" rel="stylesheet"> <title>Calculator</title> <script src="script.js" defer></script> </head> <body> <div class="calculator-grid"> <div class="output"> <div data-previous-operand class="previous-operand"></div> <div data-current-operand class="current-operand"></div> </div> <button data-all-clear class="span-two">AC</button> <button data-delete>DEL</button> <button data-operation>÷</button> <button data-number>1</button> <button data-number>2</button> <button data-number>3</button> <button data-operation>*</button> <button data-number>4</button> <button data-number>5</button> <button data-number>6</button> <button data-operation>+</button> <button data-number>7</button> <button data-number>8</button> <button data-number>9</button> <button data operation>-</button> <button data-number>.</button> <button data-number>0</button> <button data-equals class="span-two">=</button> </div> </body> </html>

You do not initialize "currentOperand".

 constructor(previousOperandTextElement, currentOperandTextElement) {
    this.previousOperandTextElement = previousOperandTextElement;
    this.currentOperandTextElement = currentOperandTextElement;
    this.currentOperand = "";
    this.clear();
  }

on the first button click, your this.currentOperand doesn't have any value, so it will be undefined variable. and undefined variable doesn't have toString property. So the solution is, u need to put condition in that appendNumber function that if the variable is undefined, then the variable just filled by the number.toString like code below

appendNumber(number) {
    if(this.currentOperand != undefined){
         this.currentOperand = this.currentOperand.toString() + number.toString();
    }else{
        this.currentOperand = number.toString();
    }
}

or if you wanna make this simpler you can define the variable in the constructor, because basicly the error is caused by Cannot read property 'toString' of undefined , so we just need to change the variable at the first state, changeing undefined variable to defined variable with

this.currentOperand = '';

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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