首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >初学者JavaScript计算器

初学者JavaScript计算器
EN

Code Review用户
提问于 2016-12-21 16:04:05
回答 5查看 7.3K关注 0票数 10

作为一个研究小组的一部分,我做了一个非常简单的JavaScript计算器。这不是为了看起来漂亮。

关于如何使代码更漂亮有什么想法吗?

代码语言:javascript
复制
/*
 * This is a simple JS calculator
 * Made by Gemtastic 2016-05-08
 */

// Gather and set up DOM elements
var numberScreen = 'screen';
var numBtns = document.getElementsByClassName('number');
var operators = document.getElementsByClassName('operator');

// Mini statemachine of if we're in the middle of operating on a number.
var operating = false;
var operand = '';

/*
 * Clears the content from the screen.
 */
function clearScreen() {
  document.getElementById(numberScreen).innerHTML = "0";
  resetOperating();
}

/*
 * Evaluates the entered numbers with the given operator.
 */
function evaluate() {
  var result;

  /* If it isn't operating or the last entered is the operator 
   * there's no point in doing anything.
   */
  if(operating && isLastEnteredNumber()){
    var content = document.getElementById(numberScreen).innerHTML;
    var numbers = content.split(operand);

    // Parse strings to be able to operate on them.
    var firstNumber = parseInt(numbers[0], 10);
    var secondNumber = parseInt(numbers[1], 10);

    // Switch the stored operator.
    switch(operand) {
      case '+':
        result = firstNumber + secondNumber;
        break;
      case '÷':
        if(firstNumber !== 0 && secondNumber !== 0) {
          result = firstNumber / secondNumber;
        } else {
          result = 0;
        }
        break;
      case '×':
        result = firstNumber * secondNumber;
        break;
      case '–':
        result = firstNumber - secondNumber;
        break;
      default:
        console.log('Something went terribly wrong! ' + operand + " is not a supported operator!");
    }
  }

  resetOperating();
  document.getElementById(numberScreen).innerHTML = result || 0;
  return result || 0;
}

/*
 * Transforms the current input or the input's value if it's a 
 * full expression but not evaluated into a percentile of itself.
 */
function percent() {
  var content = document.getElementById(numberScreen).innerHTML;
  // Cecks if you've operated two numbers but not yet pressed '=' for evaluation
  if(operating && isLastEnteredNumber()) {
    var result = evaluate();      // Evaluates the screen data
    if(result != '0') {           // if the result isn't 0 make the transformation
      content = content / 100;
    } else {                      // if it is 0 then just append a decimal for user feedback.
      content += '.0';
    }
  } else if (!operating && isLastEnteredNumber && content != '0') { // If you haven't started an operation an a not 0 character do the transformation
      content = content / 100;
  } else {
    content += '.0';              // failsafe append a decimal for user feedback.
    console.log('Bug in percent function! Operating: ' + operating + ', screen content:' + content); // Log, because if this happens we have a bug lulz.
  }
  document.getElementById(numberScreen).innerHTML = content;
  resetOperating();
}

/*
 * Adds a decimal to the screen number.
 */
function decimal() {
  document.getElementById(numberScreen).innerHTML += ".";
}

/*
 * Changes the value to be positive or negative.
 */
function editPositiveNegativeValue() {
    var content = document.getElementById(numberScreen).innerHTML;

    // Simple check if the first character on screen is - or not. If it is it just removes it.
    if(content.charAt(0) == '-') {
      content = content.slice(1);
    } else {
      content = "-" + content;
    }
    document.getElementById(numberScreen).innerHTML = content;
}

/*
 * Resets the state-machine of operation to "off".
 */
function resetOperating() {
  operating = false;
  operand = '';
}

/*
 * Checks if the last character on the screen is a number.
 */
function isLastEnteredNumber() {
  var content = document.getElementById(numberScreen).innerHTML;
  return !isNaN(content.charAt(content.length - 1));
}

/*
 * If the screen isn't showing a simple 0 append
 * to it. Else it will remplace the 0 with the
 * button's number.
 */
function numberClick(event) {
  var content = document.getElementById(numberScreen).innerHTML;
  var btnNum = event.target.innerHTML;
  
  if(content != "0"){
    content += btnNum;
  } else {
    content = btnNum;
  }
  document.getElementById(numberScreen).innerHTML = content;
}

/*
 * Called when you've pressed an operator button.
 */
function operatorClick(event) {
  var operator = event.target.innerHTML;
  var content = document.getElementById(numberScreen).innerHTML;

  switch(operator) {
    case '=':
      evaluate();
      break;
    case 'C':
      clearScreen();
      break;
    case '%':
      percent();
      break;
    case '+/-':
      editPositiveNegativeValue();
      break;
    case '.':
      decimal();
      break;
    default:
      operating = true;
      operand = operator;
      content += operator;
      document.getElementById(numberScreen).innerHTML = content;
      break;
  }
}

// Set up listeners for the operands
for(var o = 0; o < operators.length; o++) {
  operators[o].addEventListener('click', operatorClick, false);
}

// Set up listeners for the buttons
for(var b =  0; b < numBtns.length; b++) {
numBtns[b].addEventListener('click', numberClick, false);
}

clearScreen();
代码语言:javascript
复制
.btn {
  display: inline-block;
  border: 1px solid #ddd;
  padding: 5px;
  margin: 2px;
  border-radius: 5px;
  width: 1em;
  text-align: center;
}

.btn:hover {
  background-color: #eee;
  cursor: pointer;
}

.dummy {
  border: 1px solid #fff;
}
.dummy:hover {
  background-color: transparent;
}

.pad {
  position: absolute;
}

#screen {
  display: inline-block;
  margin-bottom:5px;
  padding: 5px;
  height: 1em;
  width: 90%;
  border-radius: 5px;
  border: 1px solid #ddd;
  text-align: right;
}
代码语言:javascript
复制
<div class="pad">
  <div id="screen"></div>
  <div class="row">
    <div class="btn operator">C</div>
    <div class="btn operator">%</div>
    <div class="btn operator">+/-</div>
    <div class="btn operator">÷</div>
  </div>
  <div class="row">
    <div class="btn number">7</div>
    <div class="btn number">8</div>
    <div class="btn number">9</div>
    <div class="btn operator">–</div>
  </div>
  <div class="row">
    <div class="btn number">4</div>
    <div class="btn number">5</div>
    <div class="btn number">6</div>
    <div class="btn operator">+</div>
  </div>
  <div class="row">
    <div class="btn number">1</div>
    <div class="btn number">2</div>
    <div class="btn number">3</div>
    <div class="btn operator">×</div>
  </div>
  <div class="row">
    <div class="btn dummy"> </div>
    <div class="btn number">0</div>
    <div class="btn operator">.</div>
    <div class="btn operator">=</div>
  </div>
</div>

已知问题:

  • 模数(%)不是模数,在5%2 =3中,它将显示上的数字变为百分比。
  • 显示中的数字数量没有限制
  • 它不能同时理解操作的顺序或许多计算。5 + 56 - 2 = bork。你必须做5 + 56 = 61 - 2 = 59
EN

回答 5

Code Review用户

回答已采纳

发布于 2016-12-21 18:17:13

有趣的问题,

  • 我注意到9-3*3不返回0,而是27,您没有遵循PEMDAS。
  • 就我个人而言,我将确保输入只包含数字、点和数学运算符,然后使用evaleval("9-3*3")确实正确地返回0。
  • 0.0022 *2返回零。
  • 为了提高可读性和性能,我会将html元素(如从document.getElementById(numberScreen)中找到的)赋值给更高的作用域变量。
  • 不检查当前数字中的现有期间,允许出现12.24.2016这样的数字
  • 使用纯UI函数(innerHTML)驱动逻辑是错误的。对于初学者来说,这是可以的,但是任何更高级的东西都应该驱动(id)。您不希望将“x”替换为“*”,也不必更改JS代码。
  • 您的缩进并不完美,请使用http://jsbeautifier.org/
  • 您在jshint.com上没有警告,这太棒了
票数 6
EN

Code Review用户

发布于 2016-12-21 16:45:27

要解决“显示中的数字数量没有限制”,请将javascript更改为:

代码语言:javascript
复制
if(content != "0"){
    if (content.length < 16)
        content += btnNum;
  } else {
    content = btnNum;
  }

你会说,“只有当我的屏幕上的数字少于16个时,才能添加更多的数字”。(我放16是因为我测试了你的代码,16是最大数量,直到你的div开始扩展)

“模数坏了”是什么意思?

票数 4
EN

Code Review用户

发布于 2016-12-21 16:45:45

代码看起来很好。以下是一些建议:

您引用了document.getElementById(numberScreen)很多次。为什么不在JavaScript文件的顶部指定一个较短的变量名,就像您对numBtnsoperators所做的那样?

您可以将代码分成几个部分,以便更容易地找到内容。例如,有一个变量声明部分,然后是函数部分,然后是代码执行部分。可以用注释行对各节进行区分,例如:

//--------- functions -------------------

这只是分组代码的一种方法。另一种方法可能对你更好。

您还可以使用类似的函数对您的函数进行分组,以使它们更容易找到。例如,clearScreen()resetOperating()可以相邻,evaluate()可以位于底部。在对函数进行分组时,可以检查以确保在声明函数之前没有调用函数--这不会使代码运行得更好,但它将提高可读性。

票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/150510

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档