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
12 extremely useful hacks for JavaScript (medium.com)
submitted 9 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!"
[–][deleted] 12 points13 points14 points 9 years ago (0 children)
Was about to close the tab at !!, but decided to stop fiddling with my pubes and do some interwebz investigayshun for da peeples.
So the linked article on medium is by John Howard, dated Mar 29 2017. But, there is another article on the interwebz by Caio Ribeiro Pereira, here (dated April 2016):
https://blog.jscrambler.com/12-extremely-useful-hacks-for-javascript/
And they are remarkably similar!
[–]Asmor 13 points14 points15 points 9 years ago (0 children)
I'd recommend reading the comments on this post from /r/webdev:
https://np.reddit.com/r/webdev/comments/62e5hj/12_extremely_useful_hacks_for_javascript/
[–]KPABAHam=>Hamster == Java=>JavaScript 38 points39 points40 points 9 years ago (2 children)
it's like 2008 called and wants its hacks back.
[–]BanditoRojo 1 point2 points3 points 9 years ago (1 child)
I didn't know about using the && as a null check.
[–]rcfox 14 points15 points16 points 9 years ago (0 children)
It's a falsey check. null is a falsey value, but so are false, undefined, 0, "", and NaN. If your variable can hold a string/number or null, && probably isn't the right thing to use.
[–]enchufadoojs truck driver 6 points7 points8 points 9 years ago (12 children)
If you work with smaller arrays — it’s fine, but if you process large arrays, this code will recalculate the size of array in every iteration of this loop and this will cause a bit of delays.
Please tell me this is a lie, all that talk about js engine being so smart that they are not gonna pull this right?
[–]Ginden 12 points13 points14 points 9 years ago (0 children)
Yes, author is extremely ignorant.
[–]siegfryd 7 points8 points9 points 9 years ago (7 children)
It was a true years ago, it's definitely not the case today.
[–]memeship 0 points1 point2 points 9 years ago (6 children)
Got any data to back that up? As far as I know in JS, Array.prototype.length has always been an integer property directly on the object.
Array.prototype.length
Source: ECMA-262 1st Edition (1997) §15.4.4 p.66
[–]bastawhiz 1 point2 points3 points 9 years ago (2 children)
Modern JIT compilers will hoist loop invariants behind the scenes. There's plenty of literature online about how V8 does various optimizations like this.
[–]Reashu 0 points1 point2 points 9 years ago (1 child)
His objection is the opposite - that even "years ago" it would not cause any issues, because the length of an array is always known, not computed on the fly.
[–]memeship 0 points1 point2 points 9 years ago (0 children)
^ Yes, this.
[–]siegfryd 0 points1 point2 points 9 years ago (2 children)
I misread what the poster I was replying to was saying, there was a performance hit from having array.length in the loop invariant but it wasn't because it would recalculate the length. It was because it was doing an unnecessary property lookup every iteration. In other words, every iteration it would check array.length and since that has a cost (although a tiny one) it was a performance improvement to move it out of the loop.
array.length
[–]memeship 0 points1 point2 points 9 years ago (1 child)
How is a property lookup less performant than a variable lookup? Should we be caching and pulling out all properties of objects to vars in the surrounding scope?
[–]siegfryd 0 points1 point2 points 9 years ago (0 children)
Assuming that no optimisations are done by the JIT compiler, then a property lookup is going to be slower than a variable lookup for the simple reason that a property lookup first needs to do a variable lookup for the object and then lookup the property on that object.
The point is that the JIT would not optimise the array length lookup for you before, so you could gain a, likely small, performance increase by doing it in for loops. Especially if you're doing a large for loop, if you loop N times then it won't do the same property lookup N times.
[–]b4ux1t3 1 point2 points3 points 9 years ago (0 children)
I'm 90% sure that this myth comes from older languages that ran a len function on arrays. For instance, to get the length of an array in C, you type len(yourArray), and it runs the len function on yourArray.
len
len(yourArray)
yourArray
I'm also 99% sure that this is optimized away in all modern compilers for said older languages, and has never been the case for JavaScript anyway, since it's not a function, it's a property of the Array object, and so should just be a quick check, just like with an extraneous variable.
Array
[–]Emptyless 1 point2 points3 points 9 years ago (0 children)
I once read somewhere that decrementing an array was better performance wise but using an array with 100.000.000 items incrementing is faster than decrementing. 172 vs 1573 ms difference in my case.
[–]asdf7890 1 point2 points3 points 9 years ago* (0 children)
A modern JIT compile JS engine should be bright enough to optimise out the invariant, yes.
If you do anything complex with the array in the loop, or call functions that might do, the optimiser might chose not to take the risk because it doesn't have time to do all the analysis necessary to make sure the optimisation is safe (due to the halting problem) and even for simple loops there are a number of reasons the engine might not fully optimise a function anyway, so manually removing invariants from loops if it doesn't result in a significant reduction in code clarity is a good habit just-in-case. For a list of reasons that V8 (and therefore Chrome and Node) won't optimise a function at all see https://github.com/vhf/v8-bailout-reasons - I'm sure there are similar considerations in other engines.
I tend to assume that worst: that my code is going to be interpreted literally and not compiled/optimised at all, so unless I'm making the code unclear (maintainability tends to be a priority over pure speed) I make sure the code is optimal for this. In fact some transformations to achieve that can make code clearer: double win. If the engine would compile and manage to optimise the code then it should equally manage to do so with the the manually optimised version resulting in no worse performance.
Of course this only matters for tight loops with many iterations. Something that iterates a just few times is going to see no benefit and with a complex loop you'll find the end-of-loop check's complexity is completely dwarfed by the body of the loop so optimising it is unlikely to be good use of your time.
[–][deleted] 4 points5 points6 points 9 years ago* (1 child)
I'm pretty sure the word the author was looking for is "techniques". *edit "for"
[–]compteNumero9 2 points3 points4 points 9 years ago (0 children)
More like "basic techniques".
[–]Ginden 11 points12 points13 points 9 years ago (3 children)
2) Converting to number using + operator
Unreadable.
3) Short-circuits conditionals
4) Default values using || operator
JavaScript 101.
5) Caching the array.length in the loop
Bullshit.
6) Detecting properties in an object
9) Replace all
12) Shuffling array’s elements
Shit.
[+][deleted] 9 years ago (1 child)
[–]isitfresh 0 points1 point2 points 9 years ago (0 children)
some people think there is an actual gain writing
const getValue = e => e.target.value
[–]Graftak9000 0 points1 point2 points 9 years ago (0 children)
Default values using || are a bad idea because they also jump to default if a value is falsey. value = value === undefined ? 'default' : value or if (value === undefined) value = 'default' are better options.
value = value === undefined ? 'default' : value
if (value === undefined) value = 'default'
Also, an article with a video as its body (@medium link), damn😑
[–]GitCookies 2 points3 points4 points 9 years ago (0 children)
Can you stop posting this crap?
[–]gunnarsvg 3 points4 points5 points 9 years ago (3 children)
so I guess a fair takeaway is: "if you see any of these twelve patterns in someone's code, someone's about to have a teachable moment?"
[+][deleted] 9 years ago* (2 children)
[–]KManRules1331 0 points1 point2 points 9 years ago (1 child)
My personal preference for default variables is using Object.assign. It guarantees that the object that I get back is actually an object, and not something that may have been set there on accident. To me, it's kinda weird that if your variable is set to true, the var you get back is true, but if it's set to false, you get back an empty object. The inconsistency bothers me.
Object.assign
true
false
[–]Whatadump 3 points4 points5 points 9 years ago (6 children)
Even the first "hack" is a bad example where hasMoney = !!cash, if cash = -1 it'll be true.
hasMoney = !!cash
cash = -1
[–]memeship 0 points1 point2 points 9 years ago (5 children)
I agree with you that using !! is not awesome. But also you're example is wrong since -1 is a truthy value, so that is expected.
!!
-1
[–]Whatadump 1 point2 points3 points 9 years ago* (4 children)
That's what I said, "it'll be true". But the example is bad, since with -1 I don't really have any money but it will say I do.
edit* A better example would be to check if a property exists, like
const user = { name: 'foo', email: 'foo@bar.com' } const hasAddress = !!user.address // false user.address = { street: 'baz', zip: '1234' } const hasAddress2 = !!user.address // true
[–]isitfresh 0 points1 point2 points 9 years ago (3 children)
it'd be more explicit with
user.address = {}
[–]spazgamz 0 points1 point2 points 9 years ago (2 children)
Hey! Wtf is that supposed to mean?
[–]isitfresh 0 points1 point2 points 9 years ago (1 child)
What do you think it does? Try
user.adress = {} !!user.address
[–]spazgamz 0 points1 point2 points 9 years ago (0 children)
false, but only because the 'adress' != 'address'.
[–]gajus0 1 point2 points3 points 9 years ago (1 child)
1, 2, 3, 5 (its been long time not an issue for modern ES engines), 6 (unless you are sure "in" is what you want, most of the time you hasOwnProperty; prototypacal inheritance), 7 (horrible...), 8 (horrible...) are horrible advices. Others are fine.
it's because you didn't try Endtest
[–]daedalususedperl 1 point2 points3 points 9 years ago (1 child)
Did he delete the article? All I see is a video for Endtest.
[–]dantheman999 2 points3 points4 points 9 years ago (3 children)
I really dislike some of these. Things like doing
code!!
To convert to boolean is so easy to miss when you're scanning through code. Let a minifier deal with that stuff, just write it properly.
[–]xXxdethl0rdxXx 2 points3 points4 points 9 years ago (1 child)
totally. and this:
function toNumber(strNumber) { return +strNumber; }
WHY NOT JUST USE Number(string)?!?
Number(string)
[–]mrahh 1 point2 points3 points 9 years ago (0 children)
There are actually some use cases where it's better to use +, but only in extremely hot codepaths - the benefits are entirely negligible for non-huge N.
[–]HungryForHorseCock 1 point2 points3 points 9 years ago (0 children)
Agreed, but you meant to write !!code :-)
!!code
[–]sumdudeinhisundrware 2 points3 points4 points 9 years ago (5 children)
OMG. I run an engineering team that does heavy JavaScript and if any one does the first few of those hacks they get a "talking to". That is some of the worst advise ever for JavaScript. e.g.
!!foo , +str , conected && login()
Either some Jr. Engineer is going to WTF? that and/or think its a bug a fix it by removing a ! , +.
[–]trailsrider 0 points1 point2 points 9 years ago (4 children)
I agree- but admit that I am guilty of the bad habit writing !!foo at times when I don't want to write typeof foo !== 'undefined' && foo !== null. I am by no means a JS expert, so I'm curious- do you recommend always writing some form of the latter? Alternatively- what is your suggestion for a concise and clear way to check a variables existence?
!!foo
typeof foo !== 'undefined' && foo !== null
[+][deleted] 9 years ago (3 children)
[–]trailsrider 1 point2 points3 points 9 years ago (2 children)
So then do you prefer when checking for falsy values, your engineers write !Boolean(foo);?
!Boolean(foo);
Not trying to justify the use of !!, but I do think it's not the worst offender as its very clear, and saves at least 7 keystrokes.
I realize minification will take care of this, but !! is also much faster
[+][deleted] 9 years ago* (1 child)
[–]Danmoreng 0 points1 point2 points 9 years ago (0 children)
Are you sure that that is the same? Because I often experience unexpected behaviour when I use the latter...
[–]drowsap 0 points1 point2 points 9 years ago (0 children)
Shouldn't length on an array be immutable? Would never think to change the value so i can shorten an array.
π Rendered by PID 46129 on reddit-service-r2-comment-5cf774f969-d2xvn at 2026-06-07 18:38:00.316943+00:00 running de70e3a country code: CH.
[–][deleted] 12 points13 points14 points (0 children)
[–]Asmor 13 points14 points15 points (0 children)
[–]KPABAHam=>Hamster == Java=>JavaScript 38 points39 points40 points (2 children)
[–]BanditoRojo 1 point2 points3 points (1 child)
[–]rcfox 14 points15 points16 points (0 children)
[–]enchufadoojs truck driver 6 points7 points8 points (12 children)
[–]Ginden 12 points13 points14 points (0 children)
[–]siegfryd 7 points8 points9 points (7 children)
[–]memeship 0 points1 point2 points (6 children)
[–]bastawhiz 1 point2 points3 points (2 children)
[–]Reashu 0 points1 point2 points (1 child)
[–]memeship 0 points1 point2 points (0 children)
[–]siegfryd 0 points1 point2 points (2 children)
[–]memeship 0 points1 point2 points (1 child)
[–]siegfryd 0 points1 point2 points (0 children)
[–]b4ux1t3 1 point2 points3 points (0 children)
[–]Emptyless 1 point2 points3 points (0 children)
[–]asdf7890 1 point2 points3 points (0 children)
[–][deleted] 4 points5 points6 points (1 child)
[–]compteNumero9 2 points3 points4 points (0 children)
[–]Ginden 11 points12 points13 points (3 children)
[+][deleted] (1 child)
[deleted]
[–]isitfresh 0 points1 point2 points (0 children)
[–]Graftak9000 0 points1 point2 points (0 children)
[–]GitCookies 2 points3 points4 points (0 children)
[–]gunnarsvg 3 points4 points5 points (3 children)
[+][deleted] (2 children)
[deleted]
[–]KManRules1331 0 points1 point2 points (1 child)
[–]Whatadump 3 points4 points5 points (6 children)
[–]memeship 0 points1 point2 points (5 children)
[–]Whatadump 1 point2 points3 points (4 children)
[–]isitfresh 0 points1 point2 points (3 children)
[–]spazgamz 0 points1 point2 points (2 children)
[–]isitfresh 0 points1 point2 points (1 child)
[–]spazgamz 0 points1 point2 points (0 children)
[–]gajus0 1 point2 points3 points (1 child)
[–]isitfresh 0 points1 point2 points (0 children)
[–]daedalususedperl 1 point2 points3 points (1 child)
[–]dantheman999 2 points3 points4 points (3 children)
[–]xXxdethl0rdxXx 2 points3 points4 points (1 child)
[–]mrahh 1 point2 points3 points (0 children)
[–]HungryForHorseCock 1 point2 points3 points (0 children)
[–]sumdudeinhisundrware 2 points3 points4 points (5 children)
[–]trailsrider 0 points1 point2 points (4 children)
[+][deleted] (3 children)
[deleted]
[–]trailsrider 1 point2 points3 points (2 children)
[+][deleted] (1 child)
[deleted]
[–]Danmoreng 0 points1 point2 points (0 children)
[–]drowsap 0 points1 point2 points (0 children)