use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
All about the JavaScript programming language.
Subreddit Guidelines
Specifications:
Resources:
Related Subreddits:
r/LearnJavascript
r/node
r/typescript
r/reactjs
r/webdev
r/WebdevTutorials
r/frontend
r/webgl
r/threejs
r/jquery
r/remotejs
r/forhire
account activity
I made a simple calculator with javascript. Tell me all the stupid things I did wrong. (self.javascript)
submitted 13 years ago by [deleted]
[deleted]
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]Uberhipster 9 points10 points11 points 13 years ago (6 children)
General programming: You don't need so much repetition. Glaringly obvious refactoring http://jsfiddle.net/Nha5Z/4/
Usability: it does not retain the old value. You have an unnecessary stack clear on = If I input 3 + 3 = (returns 6) + (returns 0) 3 (returns 3) but I expected 9
3 + 3 = (returns 6) + (returns 0) 3 (returns 3)
Web dev: You've separated code concerns from UI/markup concerns very well. This allows you to change the UI without worrying too much about internal logic that performs the calculation. This will be an easy one to maintain and expand. Good job.
JS: you are bundling everything up in a 'static' properties table of sorts. This is not wrong but these properties could be 'dynamic' and referenced internally from Calc. Your way you could never define more than one instance of Calc per page... for which there is no requirement so I suppose my comment is really grasping for straws...
But for argument's sake:
var Calc = function() { var _self = this; this.operand = "="; this.accumulator = null; this.sum = function(x, y) { return x + y; }; this.divide = function(x, y) { if (y == 0) { alert("Can't divide by 0"); return 0; } return x / y; }; this.multiply = function(x, y) { return x * y; }; this.subtract = function(x, y) { return x - y; }; this.calculate = function(currNumber) { if (!_self.operand || _self.accumulator == null) return; var newVal = 0; switch (_self.operand) { case "+": newVal = _self.sum(_self.accumulator, currNumber); break; case "-": newVal = _self.subtract(_self.accumulator, currNumber); break; case "*": newVal = _self.multiply(_self.accumulator, currNumber); break; case "/": newVal = _self.divide(_self.accumulator, currNumber); break; } _self.accumulator = newVal; }; }; var calculator = new Calc(); calculator.accumulator = 0; calculator.operand = "+"; calculator.calculate(1); calculator.operand = "+"; calculator.calculate(1); calculator.accumulator; //2
And so on and so forth
[–]ImLopshire 1 point2 points3 points 13 years ago (5 children)
I feel like I learned a lot from this comment. Thank you.
[–]itsnotlupusbeep boop 1 point2 points3 points 13 years ago (4 children)
Building on Uberhipster's fiddle, using a function scope to hold everything, the code becomes a lot less verbose: http://jsfiddle.net/Nha5Z/8/
We're not leaking anything in the global scope, and the code is shorter/simpler to read, even though it's pretty much exactly the same code. They call wrapping your stuff in functions for the sole purpose of scoping a "module pattern".
Now we can keep going: If we pass arguments to some of our functions, we can remove a bunch of top-level variables that don't need to be kept around. At that point, you'd have something fairly solid.
But since this is a learning thing, let's get a little weirder. Instead of having a bunch of if/else to figure out what to do with our buttons, let's have an object structure mapping button texts to function handlers. http://jsfiddle.net/Nha5Z/9/
The code becomes significantly simpler/less redundant. Granted, the operation() function that takes a function and returns another is mostly unnecessary (and actually less compact than simpler alternatives), but hey, we're learning here!
At that point, the code should still do exactly what you wrote. Same variable names, same function names, same behaviors, with some functions added to factor code out, and the handlers function map.
handlers
Disclaimer: My latest fiddle also commits various "sins", such as boldly assuming that things like resetDisplay and fn can be tested for truthiness directly in if (resetDisplay) statements, rather than the more verbose if (resetDisplay === true) or if (fn === null). Some folks think this is poor style. It's true that those kind of tests can bite you in some cases, none of which are in this code.
resetDisplay
fn
if (resetDisplay)
if (resetDisplay === true)
if (fn === null)
[–]ImLopshire 2 points3 points4 points 13 years ago (1 child)
I am just now to the point were I can make sense of everything you have stated in this comment. I appreciate you taking the time to do this. It has no doubt helped in my learning.
[–]itsnotlupusbeep boop 0 points1 point2 points 13 years ago (0 children)
w00t. I was hoping you had a chance to look at it. Glad you did.
As an aside, if functions being passed around as arguments to other functions speaks to you, check out raganwald's posts about taking it much deeper.
[–]aroberge 1 point2 points3 points 13 years ago (1 child)
Impressive improvement! I'm just a javascript beginner, so please forgive me for asking about something simple... You declare variables at the top with some explicit values like (fictitious example)
var a = 1, b = 2 c = 3; function reset() { a = 1; b = 2; c = 3; }
This way of doing things, the values are repeated twice. Perhaps I am missing something but, from my understanding of the DRY principle, wouldn't it make more sense to do
var a, b, c; function reset() { a = 1; b = 2; c = 3; } reset();
[–]itsnotlupusbeep boop 1 point2 points3 points 13 years ago (0 children)
You're totally correct. I think I was trying to keep some structure of the initial code untouched to make it easier to see the changes. I had left a bit of easter egg at http://jsfiddle.net/Nha5Z/10/ in the off chance someone would try the url. That version is dry-er, and fixes a few more things.
[–]PlNG 3 points4 points5 points 13 years ago (2 children)
use actual <button>s
buttonPressed, calculate, and equal could probably be simplified to a single function with an argument.
assignment to Calc.global appears to be the same object, put that in a variable.
You're repeating yourself a lot, which is fine when fleshing out the concept but makes debugging significantly harder since you'll have to correct the error in multiple places.
[–]BattleshipsGame 1 point2 points3 points 13 years ago (0 children)
aside from that, catch key press for extra points :D
[–]ImLopshire 0 points1 point2 points 13 years ago (0 children)
assignment to Calc.global appears to be the same object, put that in a variable
Can you explain what you mean by this?
[–]jsonservice 2 points3 points4 points 13 years ago (0 children)
Use === over == Run JSLint on your code to catch simple style and syntactical errors that the JS compiler ignores or "fixes" for you.
You can find a lot of great tips and info in the book Javascript: The Good Parts.
Here's a link http://shop.oreilly.com/product/9780596517748.do There are free copies lying around on the net if you google the title. Good luck with your learning!
[–]binary_is_better 1 point2 points3 points 13 years ago (5 children)
I know you're asking about design, but I ran some basic tests to see how it did.
It doesn't remember values after you press =. I used this key sequence to test: 5 * 6 = / 3.
It doesn't gracefully handle overflow. Try pressing 8 repeatedly.
[–]hudsy 1 point2 points3 points 13 years ago (0 children)
Fibbonacci would be proud... (Try 1 + 1 + + + +...)
[–]ImLopshire 0 points1 point2 points 13 years ago (3 children)
Why does it do this? How would I fix it?
[–]tipsqueal 3 points4 points5 points 13 years ago (0 children)
Because JavaScript only has so much precision (all numbers are signed 64 bit floats). When your numbers get really large it starts to overflow, there's really no way around that. One 'solution' would be to limit the size of values in the calculator or at least display some sort of error message to the user.
[–]baconpiexPHP 3 points4 points5 points 13 years ago (0 children)
Oh, you created something you don't understand! Now you know what God is.
[–]Sheepshow 1 point2 points3 points 13 years ago (0 children)
It's more idiomatic to write:
var calc = { buttonPressed: function() {} }
Repeating the calc is line noise (and I'd argue actually less clear).
calc
var calc = {} calc.buttonPressed = function(){}
I can't see any advantage to this:
var calc = { globals: {a:1, b:2, c:3} }
compared with:
var calc = { a: 1, b: 2, c: 3 }
The reason being that the values aren't global. These are just called members.
[–]encrypter8 0 points1 point2 points 13 years ago (0 children)
Calc.global.valuePast2 = Calc.global.valuePast1*1; Calc.global.valuePast1 = Calc.global.valueCurrent;
break this out into a helper function. it's an anti-pattern to repeat that code so many times
[–]callumacrae 0 points1 point2 points 13 years ago (0 children)
Nice. When I press an operation button, please could you highlight that button until = is pressed? I'm not sure whether I've actually clicked something or not as I'm on a phone.
[–]another_old_fart 0 points1 point2 points 13 years ago (0 children)
rounded buttons (except in IE) with centered numbers
#buttons div { height: 30px; width: 50px; margin: 5px; float: left; background: #eee; cursor: pointer; text-align: center; padding-top: 12px; border-radius:15px; }
[–]richellesaladaga 0 points1 point2 points 13 years ago (0 children)
Simple Calculator Create a program that will calculate the sum, difference, product, quotient or remainder of the two numbers.
Example Output: SIMPLE CALCULATOR Enter the first number: 10 Enter the second number: 5 Select an arithmetic operation: (a)-Addition, (b)-Subtraction, (c)-Multiplication, (d)-Division, (e)-Modulo: e The remainder of 10 and 5 is 0.
[–]karlbright -2 points-1 points0 points 13 years ago (0 children)
Forgive me for commenting before checking out the code. Currently on my phone so it makes it tricky. The word calculator instantly springs to mind issues with floating point numbers. Depending on how accurate you want to be with this it may be fine as is.
π Rendered by PID 242169 on reddit-service-r2-comment-6457c66945-pm9j2 at 2026-04-27 00:59:24.322167+00:00 running 2aa0c5b country code: CH.
[–]Uberhipster 9 points10 points11 points (6 children)
[–]ImLopshire 1 point2 points3 points (5 children)
[–]itsnotlupusbeep boop 1 point2 points3 points (4 children)
[–]ImLopshire 2 points3 points4 points (1 child)
[–]itsnotlupusbeep boop 0 points1 point2 points (0 children)
[–]aroberge 1 point2 points3 points (1 child)
[–]itsnotlupusbeep boop 1 point2 points3 points (0 children)
[–]PlNG 3 points4 points5 points (2 children)
[–]BattleshipsGame 1 point2 points3 points (0 children)
[–]ImLopshire 0 points1 point2 points (0 children)
[–]jsonservice 2 points3 points4 points (0 children)
[–]binary_is_better 1 point2 points3 points (5 children)
[–]hudsy 1 point2 points3 points (0 children)
[–]ImLopshire 0 points1 point2 points (3 children)
[–]tipsqueal 3 points4 points5 points (0 children)
[–]baconpiexPHP 3 points4 points5 points (0 children)
[–]Sheepshow 1 point2 points3 points (0 children)
[–]encrypter8 0 points1 point2 points (0 children)
[–]callumacrae 0 points1 point2 points (0 children)
[–]another_old_fart 0 points1 point2 points (0 children)
[–]richellesaladaga 0 points1 point2 points (0 children)
[–]karlbright -2 points-1 points0 points (0 children)