Проблема с локальной / глобальной областью действия и NAN - PullRequest
0 голосов
/ 04 августа 2020

Хорошо, у меня есть следующий код для создания калькулятора:

const numbers = document.querySelector('.numbers')
const display = document.querySelector('.display')
const functions = document.querySelector('.functions')
const equalClear = document.querySelector('.equalClear')

numbers.addEventListener('click', e => {
    // selecting and adding nr to display
   if(e.target.innerHTML == '1'){
       display.innerHTML += '1';
   }else if (e.target.innerHTML == '2'){
       display.innerHTML += '2';
   }else if (e.target.innerHTML == '3'){
    display.innerHTML += '3';
}else if (e.target.innerHTML == '4'){
    display.innerHTML += '4';
}else if (e.target.innerHTML == '5'){
    display.innerHTML += '5';
}else if (e.target.innerHTML == '6'){
    display.innerHTML += '6';
}else if (e.target.innerHTML == '7'){
    display.innerHTML += '7';
}else if (e.target.innerHTML == '8'){
    display.innerHTML += '8';
}else if (e.target.innerHTML == '9'){
    display.innerHTML += '9';
}else if (e.target.innerHTML == '0'){
    display.innerHTML += '0';
}
});

functions.addEventListener('click', e => {
    // selecting a function and adding it to the display
    if(e.target.innerHTML == 'Add'){
        display.innerHTML += '+';
        functionVal = add();
    } else if(e.target.innerHTML == 'Subtract'){
        display.innerHTML += '-';
        functionVal = subtract();
    } else if(e.target.innerHTML == 'Multiply'){
        display.innerHTML += '*';
        functionVal = multiply()
    } else if(e.target.innerHTML == 'Divide'){
        display.innerHTML += '/';
        functionVal = divide();
    }else{
        display.innerHTML + 'Error'
    }
    numberVal = display.innerText; //creating variable with value of nr in display
    console.log(numberVal, "numberVal");
    console.log(functionVal, "functionVal");
});

equalClear.addEventListener('click', e => {
    if(e.target.innerHTML === 'Clear'){
        display.innerHTML = "";
    } 
    else if(e.target.innerHTML = '='){
    }
})

//functions for calculator

function add(variable1, variable2) {
    return variable1 + variable2;
};

function subtract(variable1, variable2) {
    return variable1 - variable2;
}

function multiply(variable1, variable2) {
    return variable1 * variable2;
};

function divide(variable1, variable2) {
    return variable1 / variable2;
}

// operation in calculator

function operate(operator, num1, num2){
   operate = operator, num1, num2;
}

operate(functionVal(numberVal,5))
console.log(operate, "this is an operation");

Я определяю «functionVal» и «numberVal» в «functions.addEventListener». Но когда я пытаюсь вызвать их в функции «работать» в нижней части кода, я получаю, что «functionVal» и «numberVal» не определены. Я знаю, что это происходит из-за того, что он находится в локальной области видимости в функции "functions.addEventListener", и я попытался добавить "var" для каждого из них перед блоком кода, чтобы дать им глобальную область видимости. Но это просто не сработает, и я немного схожу с ума, пытаясь выяснить, как иметь возможность вызывать их в моей функции «управлять».

Кроме того, когда я вызываю «functionVal» в консоли .log "в" functions.AddEventListener "Я понимаю, что" functionVal "- это NAN, который, как я знаю," не число ", но разве он не должен отображать фактическую функцию, которую я дал ей значение? Я установил, что если вы нажмете «добавить» в HTML, значение «functionVal» станет функцией «добавить», которую я определил в нижней части кода. Я не уверен, что здесь происходит не так, поэтому любая помощь будет очень признательна.

В функции «работа» я присвоил второму параметру значение 5 только для тестирования, но добавлю фактическое значение " второе число »на дисплее, как только я смог разобраться в проблемах.

Благодарен за любую помощь!

С уважением, A JS noob

1 Ответ

0 голосов
/ 04 августа 2020

Хорошо, поначалу это действительно нехорошо, зачем вам когда-либо проверять равенство (и использовать оператор === для тех же типов):

numbers.addEventListener('click', e => {
    // selecting and adding nr to display
   if(e.target.innerHTML == '1'){
       display.innerHTML += '1';
   }else if (e.target.innerHTML == '2'){
       display.innerHTML += '2';
   }else if (e.target.innerHTML == '3'){
    display.innerHTML += '3';
}else if (e.target.innerHTML == '4'){
    display.innerHTML += '4';
}else if (e.target.innerHTML == '5'){
    display.innerHTML += '5';
}else if (e.target.innerHTML == '6'){
    display.innerHTML += '6';
}else if (e.target.innerHTML == '7'){
    display.innerHTML += '7';
}else if (e.target.innerHTML == '8'){
    display.innerHTML += '8';
}else if (e.target.innerHTML == '9'){
    display.innerHTML += '9';
}else if (e.target.innerHTML == '0'){
    display.innerHTML += '0';
}
});

Вы можете переписать это так:

numbers.addEventListener('click', e => { 
    display.innerHTML += e.target.innerHTML;
}

И, если я правильно понял, numbers должен быть массивом кнопок с числами, но querySelector возвращает только первое вхождение, поэтому он вернет только первую кнопку. Вы должны использовать querySelectorAll и переписать его следующим образом:

const numbersButtons = document.querySelectorAll('.numbers');
// convert to array, because we can't iterate over querySelectorAll result
Array.from(numbersButtons).forEach((button,index) => {
    button.addEventListener('click', e => {
        display.innerHTML += e.target.innerHTML;
    }
});

Функции, вероятность, тоже должны быть массивом, и вы можете сделать код более понятным, используя, например, карту функций:

const functionsMap = {
    '+': add,
    '-': subtract
    // and other functions..
}

И назовите их так:

// will return add function
const targetFunc = functionsMap['+'];
// call with parameters
targetFunc(1,2);

И да, когда вы сделаете это:

 functionVal = divide();

Вы не передаете ссылку на функцию, вы выполняете его, поэтому functionVal сохранит результат выполнения функции, и да, он вернет NaN, потому что вы выполняете его без параметров, попробуйте это в консоли:

function add (a,b){return a + b}
console.log(add());

Еще есть много ошибок, которые я не буду анализировать, поэтому советую go вернуться в самое начало и хорошо позаботиться о том, что вы делаете.

...