Простой четыре функции калькулятора


В основном я писал этот калькулятор как своеобразный тест JavaScript для себя. Это простой калькулятор с сложение, вычитание и умножение. Я сделал некоторые улучшения к нему, прежде чем отправлять это.

В этот момент я надеялся, что кто-то мог просто указать на некоторые способы, я мог бы очистить этот код больше, в основном как упражнение в обучении. Я включил в JavaScript, а затем в HTML.

    displayNum = "";
    storedNum = "";
    operation = 0;
    queuedOperation = 0;
    calculationFinished = false;

function clearDisplay() {
    // Select the calculator's display
    var display = document.getElementById("display");

    // Clear the global variables and the display
    displayNum = "";
    storedNum = "";
    operation = 0;
    queuedOperation = 0;        
    display.value = displayNum;

}

function numInput(num) {
    // Select the calculator's display
    var display = document.getElementById("display");

    // Check if the display is empty and the number being pressed is 0
    // This is to make sure the first number isn't 0 because then javascript thinks we are using OCTAL (Base eight)
    if ((display.value == "") && num == "0") {
    // If it is, do nothing
      return;
    }
    // Check if a calculation has finished
    // If it has replace the number in the display (the answer to the calculation with the number
    // that was just pressed and change calculation finished back to false 
    else if (calculationFinished == true) {
        display.value = num;
        calculationFinished = false;
    }
    // if neither of these is the case input the numbers as usual
    else {
      display.value += num;
    }
}

function insertDecimal(dec) {
    // Select the calculator's display
    var display = document.getElementById("display");

    // Loop through the current number to make sure there isn't already a decimal
    for (i = 0; i < display.value.length; i++)
        if (display.value.charAt(i) == '.') {
            // If there is, do nothing
            return;
        }
    // If there isn't add a decimal to the end of the displayed number
        display.value += dec;
}

function setOperation(command) {
    // Select the calculator's display
    var display = document.getElementById("display"),
            displayNum = display.value;
    // eval both the numbers to remove quotes
    // otherwise 4 + 5 will be "4" + "5" which in JS will equal 45
            evalDisplay = eval(displayNum),
            evalStored = eval(storedNum);

    // Check if there is a queued operation
    // If there is a queued operation calculate it
    // Then set the stored number to total of the calculation       
    if (queuedOperation == 0) {
        storedNum = display.value;
    }
    else if (queuedOperation == 1) {
        storedNum = evalStored + evalDisplay;
    }
    else if (queuedOperation == 2) {
        storedNum = evalStored - evalDisplay;
    }
    else if (queuedOperation == 3) {
        storedNum = evalStored * evalDisplay;
    }

    // Check what command was put into the calculator
    // Then set the operation to the correct number
    if (command == 'add') {
        operation = 1;
    }
    else if (command == 'subtract') {
        operation = 2;
    }
    if (command == 'multiply') {
        operation = 3;
    }

    // Queue up an operation for enterint multiple  commands without hitting equals
    // i.e. 10x4+8-9+3=
    queuedOperation = operation;
    // Clear the display in order to receive a new number
    display.value = '';
}

function calculate() {
    // Select the calculator's display
    var display = document.getElementById("display");
            displayNum = display.value;
    var evalDisplay = eval(displayNum),
            evalStored = eval(storedNum);

    // Do the math
    if (operation == 1) {
        displayNum = evalStored + evalDisplay;
    }
    else if (operation == 2) {
        displayNum = evalStored - evalDisplay;
    }
    else if (operation == 3) {
        displayNum = evalStored * evalDisplay;
    }
    // Change display to the answer
    display.value = displayNum;
    if (operation != 0)
        calculationFinished = true;
    // Clear all the global variables
    // Necessary in case the user wants to make a calculation using the answer
    operation = 0;
    queuedOperation = 0;
    displayNum = "";
    storedNum = "";
}
<!DOCTYPE html>
    <html>
        <head>
            <script type="text/javascript" src="calculator.js"></script> 
            <link rel="stylesheet" href="style.css" />
        </head>
        <body>
        <form class="calcForm" name="calculator">
            <input type="text" class="calcDisplay" id="display" />
            <div class="calcRow">
                <input type="button" class="calcButton" value="7" onclick="numInput('7')" />
                <input type="button" class="calcButton" value="8" onclick="numInput('8')" />
                <input type="button" class="calcButton" value="9" onclick="numInput('9')" />
                <input type="button" class="calcButton" value="+" onclick="setOperation('add')" />
            </div>
            <div class="calcRow">
                <input type="button" class="calcButton" value="4" onclick="numInput('4')" />
                <input type="button" class="calcButton" value="5" onclick="numInput('5')" />
                <input type="button" class="calcButton" value="6" onclick="numInput('6')" />
                <input type="button" class="calcButton" value="-" onclick="setOperation('subtract')" />
            </div>
            <div class="calcRow">
                <input type="button" class="calcButton" value="1" onclick="numInput('1')" />
                <input type="button" class="calcButton" value="2" onclick="numInput('2')" />
                <input type="button" class="calcButton" value="3" onclick="numInput('3')" />
                <input type="button" class="calcButton" value="x" onclick="setOperation('multiply')" />
            </div>
            <div class="calcRow">
                <input type="button" class="calcButton" value="0" onclick="numInput('0')" />
                <input type="button" class="calcButton" value="." onclick="insertDecimal('.')" />
                <input type="button" class="calcButton" value="C" onclick="clearDisplay()" />
                <input type="button" class="calcButton" value="=" onclick="calculate()" />
            </div>
        </form>
    </body>
</html>



62516
5
задан 18 декабря 2011 в 01:12 Источник Поделиться
Комментарии
2 ответа


  • Все эти глобальные приводят меня в дрожь. То же самое с эвалС.

  • Вы делаете математику в двух местах -- в расчет и в setOperation. Считаю, что дисплей.значение = x; storedNum = дисплей.стоимость; дисплей.значение = " имеет такой же эффект, как storedNum = х; дисплей.значение = ". Перевод: вы можете позвонить вычислить() от setOperation, а не повторять себя. Это также устраняет необходимость для queuedOperation.

  • insertDecimal петли над всей строкой, проверяя каждый чар для равенства с '.'. Лучше будет, если (дисплей.значение.метод indexOf('.') != -1) возвращение;. Или даже лучше, чем, если (дисплей.значение.метод indexOf('.') === -1) { /* добавить точку */ }.

  • insertDecimal также запятой в качестве аргумента. Это не имеет смысла, поскольку вы не используете его, чтобы добавить ничего, кроме десятичной точки. Потерять арг.

  • Стоимость операции не очевидна. 0, 1, 2, или 3? Эти цифры ничего не значат для меня. Вы не ограничены числами, вы можете использовать оператор символы, имена функций, или даже сами функции. В какой момент Вы могли избавиться от если/еще заявления для математика.

  • Мировой displayNum никогда не используется. На самом деле, displayNum могут быть исключены полностью, так как его единственной целью является, чтобы держать разобранным количество. Считают, что рефакторинг операции, вы только когда-нибудь понадобится значение в одном месте, и вы можете преобразовать его прямо там и не имея другой переменной.

  • Дисплей не работает совсем верно, когда я рассчитать 125 + 0 или 125 * 0. Я получить правильный результат, благодаря счастливой случайности. (Пустая строка превращается в 0.) Но 0 я поступил не появляется в текстовом поле.

  • Ты повторяешься, установив глобальные переменные в начале скрипта, а потом делать то же самое в clearDisplay. У слушателя события называют clearDisplay когда страница будет готова, и вы будете иметь только одно место, чтобы изменить вещи.

  • Относительно, имея дисплей понятно, сам момент, когда вы нажмите кнопку оператора немного режет слух. Калькуляторы, как правило, не работают, что путь, и если вы собираетесь сделать один, вы должны сделать его работать так, как люди привыкли. Кроме того, очистили окон все равно как-то странно. Когда вам понятно, калькулятор, как правило, показывает '0'.

  • Относительно, У меня есть личная ненависть к комментариям, которые говорят очевидное. Они просто добавить шума.

С этим исправлено:

function clearDisplay() {
var display = document.getElementById('display');
display.value = '0';
storedNum = '0';
calculationFinished = true;
operation = operations.none;
}

function clearPreviousResult() {
var display = document.getElementById('display');
if (calculationFinished) {
display.value = '0';
calculationFinished = false;
}
}

function numInput(digit) {
var display = document.getElementById('display');
clearPreviousResult();
// Get rid of a 0 if it's the only thing in there.
// This particular way of doing it lets you enter a 0 and have it show up,
// as well as leaving a 0 for the decimal point to snuggle up to.
if (display.value === '0') display.value = '';
display.value += digit;
}

function insertDecimal() {
var display = document.getElementById('display');
clearPreviousResult();
if (display.value.indexOf('.') === -1) display.value += '.';
}

operations = {
// no-op. Takes the right side, and just returns it. Since the right side is the
// display value, and calculate() sets display.value, this effectively makes
// calculate() say "display.value = +display.value".
none: function(left, right) { return right; },

// Math ops.
add: function(left, right) { return left + right; },
subtract: function(left, right) { return left - right; },
multiply: function(left, right) { return left * right; }
};

function setOperation(command) {
var display = document.getElementById('display');
calculate();
storedNum = display.value;
if (operations.hasOwnProperty(command))
operation = operations[command];
}

function calculate() {
var display = document.getElementById('display');
display.value = operation(+storedNum, +display.value);
calculationFinished = true;
operation = operations.none;
}

if ('addEventListener' in window)
window.addEventListener('load', clearDisplay);
else
window.attachEvent('onload', clearDisplay);

4
ответ дан 19 декабря 2011 в 10:12 Источник Поделиться

Заменить функцию eval(displayNum) с +displayNum - функция eval выполняет значение, которое не только медленнее, он уязвим к XSS.

Кроме того, что вы будет выглядеть на вас объектно-ориентированных (ОО), чтобы объединить код в логические группы и взять код функций и переменных вне рамки окна. Хорошие Посты:

https://stackoverflow.com/questions/907225/object-oriented-javascript-best-practices

https://stackoverflow.com/questions/1908443/what-are-good-javascript-oop-resources

3
ответ дан 18 декабря 2011 в 01:12 Источник Поделиться