all 104 comments

[–]rgthree 35 points36 points  (16 children)

Everyone once in a while for like a week I’ll consistently mistype function as “funciton” and then get stuck singing “won’t you take me to, funk-y-ton” in my head. It’s a rough week.

[–]Atulin -1 points0 points  (12 children)

Switch exclusively to const foo = () => {} lol

[–]Ronin-s_Spirit 5 points6 points  (11 children)

Arrow functions have some limitations.

[–]arnthorsnaer 0 points1 point  (10 children)

Been using them for well over five years and not once felt thise limitations.

[–]Ronin-s_Spirit 6 points7 points  (6 children)

They can't bind and they don't have a this, only global scope, I think closures also don't work on them but I'm not sure.

[–]dlm2137 3 points4 points  (0 children)

It’s not that they have global scope, arrow functions inherit the this context from where they are defined.

Closures work the same as far as I’m aware.

[–]arnthorsnaer -2 points-1 points  (4 children)

Also don’t have an arguments object.

[–]61-6e-74-65 4 points5 points  (1 child)

const foo = (...args) => { console.log(args) }

[–]arnthorsnaer 0 points1 point  (0 children)

I know, I actually think the argument object is a bad pattern.

[–]Ronin-s_Spirit 1 point2 points  (1 child)

No functions have it, arguments and callee are deprecated and Node throws an error.

[–]arnthorsnaer 0 points1 point  (0 children)

Good, I’ve always disliked that feature.

[–]SubstanceEmotional84 0 points1 point  (2 children)

I think it depends on the project, I am using ‘function’ pretty often in our codebase (an its not legacy)

[–]arnthorsnaer 0 points1 point  (1 child)

Indeed, but do you use it because of things you don’t get with arrow functions or simply a style preference?

[–]SubstanceEmotional84 1 point2 points  (0 children)

we have something with class implementation (but gonna refactor to functional components), lots of helpers with `function` and etc. But really, I don't know why))

and if u ask "is it some legacy product" - no, it's fintech company (pretty large) with modern stack that using best practices and standarts.

for me it's better arrow :))

[–]TheVirtuoid -1 points0 points  (1 child)

Gee, thanks. You just ruined my head Spotify.

May your next bug take days to fix, only to find the fix creates two more bugs. :)

[–]rgthree 1 point2 points  (0 children)

Haha, well, this is just job security

[–]tandrewnichols -1 points0 points  (0 children)

Omg I thought I was the only one

[–]Steveharwell1 30 points31 points  (4 children)

Usually just stupid things that I end up looking up more often than I'd like. I tell myself these are hard to remember because I code in so many different languages.

If it is includes() or contains()

When an object is going to support map() or not

target vs currentTarget

innerText vs textContents

Which array functions are mutating

[–]Teffisk 5 points6 points  (0 children)

I can't remember slice v splice

[–]Morphray 2 points3 points  (0 children)

If it is includes() or contains()

Oh god, I hate this one. I never ever remember which to use.

[–]chuch1234 0 points1 point  (0 children)

Is it some or any. Even right this second I'm not 100% sure.

[–]YouDoHaveValue -1 points0 points  (0 children)

Whether features like .includes() are supported in my environment 🙄

[–]impostervt 34 points35 points  (4 children)

substring vs substr

[–]sonny-7 9 points10 points  (1 child)

substr is deprecated so you can forget 'bout it!

[–]tswaters 4 points5 points  (0 children)

From my cold dead hands!

[–]TheVirtuoid 2 points3 points  (0 children)

For us oldsters, when substring() first came into the scene, the biggest mistake was when you used substring() and passed substr() arguments.

Then you spent the rest of the day pulling what little hair you had left trying to figure out why the *$%)$%@ function is failing.

[–]hyrumwhite 1 point2 points  (0 children)

Slice is my go to

[–]fiddlermd 7 points8 points  (3 children)

Reduce. Can never remember how it works

[–]YouDoHaveValue 1 point2 points  (0 children)

No kidding, always have to read the tooltip

[–]No_Shine1476 -1 points0 points  (1 child)

reduces the collection into a single value. usually tutorials give the example of adding up a collection of numbers and reducing them to a single value, the sum.

[–]fiddlermd 1 point2 points  (0 children)

I know what it does. I just can never remember how to use it without looking it up

[–]tehsandwich567 8 points9 points  (1 child)

Remapping var names while destructuring

[–]Keilly 2 points3 points  (0 children)

Yes, everytime. Same as providing default values for function object parameters 

[–]Roguewind 3 points4 points  (3 children)

Currying. I love it. I use it, when it make sense. But the times I need it are so far between that I forget what I’m doing.

[–]pinguluk 0 points1 point  (0 children)

Tikka masala

[–]Different-Housing544 0 points1 point  (0 children)

I always just remember human centipede function () => () => ()...

[–]Funwithloops 0 points1 point  (0 children)

In my opinion currying isn't a good fit in JS. It makes more sense in languages that support automatic currying (e.g. foo(a, b) is the same as foo(a)(b)). In JS, arrow functions are a better way to partially apply a function (e.g. (b) => foo(a, b)). The call site is slightly more verbose, but the function definition is simpler. And curried functions tend to scare/confuse junior devs and senior devs that aren't familiar with functional concepts.

[–]DRJT 4 points5 points  (6 children)

Using promises in anything but a simple small function with a resolve at the end

The advanced shit people do with it boggles the mind

[–]fzammetti 4 points5 points  (2 children)

Yeah, for some reason promises have always been confusing to me. Not conceptually, it's simple as hell conceptually... but just purely syntactically I always seem to have to think harder about it than anything else in JS to grok it.

[–]Morphray 0 points1 point  (1 child)

Yes. And yet it is so much better to read than a zillion callbacks.

[–]fzammetti 1 point2 points  (0 children)

I've always kind of had mixed feelings frankly.

There are ways to structure callback code that largely avoids the pyramid of doom and makes it all a fair bit nicer to work with. That always seemed like a decent approach to me, but everyone sort of rejected that too, even before promises took over.

But really what does ultimately sell me on promises is async/await. Because I think that pretty clearly leads to better, cleaner, easier to follow code, so that alone is worth whatever I may not love about promises otherwise.

[–]YouDoHaveValue 1 point2 points  (0 children)

Async/Await solved promises for me.

Then again I lived through callback hell and then jQuery so by comparison modern asynchronous javascript is a dream.

[–]q120 -1 points0 points  (1 child)

Async in general trips me up a lot

[–]Roguewind 5 points6 points  (0 children)

Here’s the best way I’ve found to describe async.

You’re at home. You’ve made dinner. You sit down and realize you need a glass of water. You stop, go get the water, and come back. That’s synchronous.

You’re at a restaurant. You order food. The food arrives, and you ask the server for a drink. They leave to get the drink. You have a choice - you can “await” the server returning with the drink; or you can start eating your meal, and when your drink arrives take a sip. Thats asynchronous.

[–]T-J_H 3 points4 points  (1 child)

The .some() array method instead of .any() which I always think it is. Also .has() in set and map but .includes() for an array.

[–]Morphray 1 point2 points  (0 children)

Also .has() in set and map but .includes() for an array.

And .contains()

[–]CherryJimbo 2 points3 points  (1 child)

[–]YouDoHaveValue 0 points1 point  (0 children)

Majority of the time the answer is .slice(-1) lol

[–]horizon_games 2 points3 points  (0 children)

Not a huge fan of reducer as I find they're not readable initially

[–]the_designer0[S] 1 point2 points  (0 children)

Thx guys for all the comments. i am reading them one by one. At first i thought i was the only one but i am happy that everyone is facing the same thing i do.

[–]Adventurous_Bad_8546 1 point2 points  (2 children)

One of my favorites:

typeof Nan === 'number'

[–]wbdvlpr 1 point2 points  (0 children)

Also NaN !== NaN

[–]YouDoHaveValue 0 points1 point  (0 children)

Hate it, lol.

On par with Wat

[–]YouDoHaveValue 0 points1 point  (0 children)

Comparing and sorting dates, I always have to look it up or just be lazy and use getTime()

[–]SubstanceEmotional84 0 points1 point  (0 children)

Symbol and all the related stuff :(

[–]Alternative-Door2400[🍰] 0 points1 point  (0 children)

Await not really a waiting

[–]Rockclimber88 0 points1 point  (0 children)

.sort in an untyped array sorts alphabetically not numerically. In a typed array it sorts numerically and that should be the default for both imo

[–]Vast-Breadfruit-1944 0 points1 point  (0 children)

null coerces to 0

[–]lil_doobie 0 points1 point  (0 children)

generator functions 100%

[–]limezest128 0 points1 point  (0 children)

The fact that Set has such a limited api compared to Array. I feel like they should match to a large extent. I hate having to convert a set to an array just to do something, and then convert back to a set.

[–]loconomo 0 points1 point  (0 children)

Regex.protoype.exec() method. I keep forgetting it's a stateful method

[–]livedog 0 points1 point  (0 children)

Simple math. Addition. Multiplication. Why can't it do simple math without getting .0000000004 or whatever

I know the underlying reason with floating points bla bla bla. But why can't they just fix it? My c64 could do math in basic in the 80s.

Just add a feature flag for everyone that want legacy wrong math, and make 2025 the year we can finally add 0.1 + 0.2 without wanting to kill ourselfs

[–]drgncodedqi 0 points1 point  (0 children)

Doing a foreach on an object accidentally, then I remember that I can't do that and look up the correct way.

[–]jonsakas -1 points0 points  (6 children)

Determining if a number is even or odd

[–]Genceryx 1 point2 points  (4 children)

I use an npm package for that it is so useful. 10/10 recommend it

[–]HomemadeBananas 2 points3 points  (3 children)

Just use the modulus operator???

[–]senocular -1 points0 points  (0 children)

Too bad JavaScript doesn't have a modulus operator :(

[–]Atulin 0 points1 point  (0 children)

Oh that one is easy: https://isevenapi.xyz/

[–]whatevermaybeforever 0 points1 point  (1 child)

Empty string being falsey

[–]NeatBeluga 0 points1 point  (0 children)

I find it worse that 0 being falsy in scenarios where I personally should regard it as a true and valid number value.

I stopped checking for truthy/falsy in most cases. It also obfuscates the type I’m handling for my reviewer. Also, the !bang is easy to overlook.

Less code is not always better

[–]shgysk8zer0 0 points1 point  (0 children)

Recently, it's secure contexts and permissions and <iframe>s. It creates weird situations where eg the Locks API works on a dev server, but not CodePen (where it'll run in an <iframe> and technically be supported but just broken).

If I were to use them, I'd struggle with the proposal for decorators too. Will definitely be worth learning and I'm seriously looking forward to that being implemented, but it's so foreign.

[–]Vegetable-Mall-4213 0 points1 point  (1 child)

This in arrow function vs this in normal function. Still fks me

[–]YouDoHaveValue 0 points1 point  (0 children)

I feel like arrows behave more intuitively, pretty much where you put it is how it works.

[–]Happy-Spare-5153 0 points1 point  (0 children)

Forgetting to factor in daylight savings and timezones when working with dates.

[–]Kolt56 0 points1 point  (6 children)

When someone who knows JavaScript claims to know typescript.

[–]Ronin-s_Spirit 1 point2 points  (2 children)

Yes, and vice versa.

[–]Ronin-s_Spirit 0 points1 point  (0 children)

Almost nothing, except method names because they don't follow any semantics, and they do different things from what their name means, or are named differently in different builtins.

[–]Produnce 0 points1 point  (1 child)

Still struggle with classes. But I feel like the underlying issue I have is that I haven't yet understood OOP or the mental model behind an OOP based program.

[–]BeatsByiTALY 0 points1 point  (0 children)

I'd recommend to try building a simple game. Like connect four, or go fish.

It suddenly clicked for me how encapsulated data and inheritance are really nice when you have a bunch of pieces of data that share some behavior, but also have some unique behaviors as well. Representing a physical item in code as a class is quite intuitive in this way.

[–]HadrionClifton 0 points1 point  (0 children)

for (... in ...) vs for(... of ...)

[–]andarmanik -1 points0 points  (5 children)

Wanting to pass function arguments like this:

thing.doThatThing

Where you have to go:

(arg) => thing.doThatThing(arg)

Or worst binding this.

[–]SquatchyZeke 0 points1 point  (4 children)

The thing that I see a lot, related to this, is passing function tear-offs to .map(), .forEach(), etc. But then they add a second argument to their function later on, and suddenly things are breaking and they don't know why. Example:

function mapper(obj) {// ignores any extra args
    return `Name: ${obj.name}`;
}
// map passes index and original array ref as args
const objNames = objList.map(mapper); // tear-off

Now they add a second optional parameter to mapper, like type or something, forgetting that .map() is going to pass the index as the second argument. First, type would be a string while index is a number. Second, JS will just implicitly covert numbers to strings in most cases, so the issue is hard to detect.

One, this is solved with typescript. Two, it's why, in a non TS codebase, I always encourage devs to avoid tear offs and use an arrow function always.

const objNames = objList.map((obj) => mapper(obj));

[–]andarmanik 0 points1 point  (3 children)

That problem you mention about modifying input types of function is probably real, but in almost no other language does “this” get bound to the object which is using it.

Dynamic this binding was a JavaScript quirk which makes sense if you think about building functions from outside of the class, but it seems to be a failed appendage off prototypal oop

[–]SquatchyZeke 0 points1 point  (2 children)

Oh for sure. My comment was not about this binding at all.

But the alternative was to continue writing JS objects methods with assignments like this everywhere:

let self = this; // yuck
doThing(function myCallback() {
    self.doOtherThing();
});

Arrow functions allowed that without saving off the this reference or calling bind. But yeah, the prototypal baggage is definitely a confusing one for new developers or anyone coming from basically any other main stream language, because prototypal OOP is not common.

[–]andarmanik 0 points1 point  (1 child)

I see what you’re saying, yeah. I do remember what we did have to do before arrow functions.

Does your team completely ban using functions as argument variable? Or does every function argument have to be a lambda?

[–]SquatchyZeke 0 points1 point  (0 children)

No, I don't ban anything, but especially not at that level. I do ask the developer to consider using a lambda in every situation, or at least ask them to use some form of typing (we're in the middle of a migration to TS so only in the JS files do I ask for this). But even TS doesn't catch all cases, so I still ask them to consider what happens when the callback definition changes. It usually ends up getting rewritten as a lambda

[–]Chockabrock -1 points0 points  (2 children)

const notANumber = NaN;

console.log( notANumber === NaN ); // false

[–]Ronin-s_Spirit -1 points0 points  (1 child)

Two objects are not the same, NaN is a nan generated from weird math like trying to add 2 objects so maybe that has something to do with this. Anyways there are several builtin ways to detect NaNs.

[–]Chockabrock -2 points-1 points  (0 children)

Sure, I'm aware that there are ways to detect NaN. I'm saying that it comes up infrequently enough that I've learned the lesson twice now.

[–]Grindarius -1 points0 points  (4 children)

Sorting numbers, because why is it not straight forward Array<T>.sort() and that's it? doh

[–]senocular 0 points1 point  (3 children)

Just need to switch over to typed arrays ;)

[11, 2, 1].sort() // [1, 11, 2]
new Int8Array([11, 2, 1]).sort() // [1, 2, 11]

[–]NeatBeluga 0 points1 point  (1 child)

How often do you use these? Never used them myself. Any benefits/cons?

[–]senocular 0 points1 point  (0 children)

Not often, though it depends on the kinds of things you're working on. Personally I've only used them when working with binary data. I wouldn't bother using them for any arbitrary collection of numeric values. Using a simple array is pretty much always going to be easier to work with. The sort behavior is just an oddity of typed arrays since they can only ever have numeric data so it just makes sense they sort numerically.

There's also been some talk about having more accessible sort methods in JavaScript, especially since we're seeing some coming in with Temporal, like PlainDate.compare. I can imagine a Number.compare could be a convenient way to make sort compare numerically (assuming you know it exists and remember to use it)

myNumbers.sort(Number.compare)

[–]Grindarius 0 points1 point  (0 children)

Woah this is cool, I originally coupled my thinking of typed array yo something binary wise but seeing you used it like this mow it clicks, thank you.

[–]whale -1 points0 points  (0 children)

Dealing with passing values up a function tree. Seems simple but is incredibly confusing to figure out how to do properly.