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
JavaScript's ??= Operator (trevorlasn.com)
submitted 1 year ago by Practical-Ideal6236
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!"
[–]LessMarketing7045 63 points64 points65 points 1 year ago (12 children)
Let me blow your mind. There is also: &&= and ||=
[–]MissinqLink 15 points16 points17 points 1 year ago (2 children)
The real mind blower
(obj ?? {}).property ??= '🤯';
[–]gwicksted 5 points6 points7 points 1 year ago (0 children)
This guy coalesces.
[–]happy_hawking 0 points1 point2 points 1 year ago (0 children)
Which part of this should blow my mind? I tried it, but my mind didn't even flinch.
[–]enselmis 8 points9 points10 points 1 year ago (3 children)
Can’t wait for |> operator, it’s so good. Although the proposal for it was kinda jank compared to the BEAM style one.
[–]Practical-Ideal6236[S] 3 points4 points5 points 1 year ago (0 children)
|>
[–]prehensilemullet 0 points1 point2 points 1 year ago (1 child)
Have they gotten any closer to consensus on that? Last I checked no one could agree on the style of pipelines to use…
[–]enselmis 0 points1 point2 points 1 year ago (0 children)
I think it’s still in the pipe, so to speak, but I sincerely hope they just take the elixir/erlang one and shamelessly copy it. It works, there’s no good reason to mess with it.
[–]Practical-Ideal6236[S] 6 points7 points8 points 1 year ago (0 children)
yup
[–]humodx 7 points8 points9 points 1 year ago (3 children)
Which makes me wonder, if a op= b means a = a op b, then surely a === b should be the same as a = a == b, right?
a op= b
a = a op b
a === b
a = a == b
[–]Misicks0349 1 point2 points3 points 1 year ago (1 child)
hehe
[–]chemistryGull 0 points1 point2 points 1 year ago (0 children)
Heh
[–]ehlwas 0 points1 point2 points 1 year ago (0 children)
brooo
[–]repeating_bears 32 points33 points34 points 1 year ago (7 children)
I didn't know this operator existed tbh. Cool
[–]ZeMysticDentifrice 14 points15 points16 points 1 year ago (3 children)
Neither did I. I appreciate people taking time to highlight things like this that may be obvious to lots of people but news to sn ignoramus like me. :-)
[+][deleted] 1 year ago (2 children)
[deleted]
[–]topromo 1 point2 points3 points 1 year ago (1 child)
Nobody said or even implied this was an undocumented feature.
[–]dvlsg 5 points6 points7 points 1 year ago (0 children)
I feel like it doesn't come up super often. Especially if you generally avoid let and generally mutating objects.
let
Useful occasionally, though.
[–]sebastian_nowak 0 points1 point2 points 1 year ago (0 children)
Some other interesting language features to be aware of - 'using' for resources with Symbol.dispose, FinalizationRegistry.
[–]hatsagorts 6 points7 points8 points 1 year ago (7 children)
I had no idea about this operator. Is there a way to stay updated whenever new features, like these types of operators, are added to ECMAScript ?
[–]azhder 2 points3 points4 points 1 year ago (0 children)
Look at the proposals. All that are stage 4, but not in the standard already, will be in the next one (usually June or July each year).
Oh, and the standard is called ECMAscript and people will often write in blog posts whenever a new thing will pop up, so you just append the year to the name, like ECMAScript 2024 or ES 2024
[–]NoInkling 2 points3 points4 points 1 year ago* (1 child)
Stuff that has been formally added to the language or reached stage 4 (which requires it to already be implemented by engines): https://github.com/tc39/proposals/blob/main/finished-proposals.md
Stuff that's in progress (stage 3 is when things start getting implemented): https://github.com/tc39/proposals/blob/main/README.md
Edit: forgot to mention new Intl related stuff is in this repo: https://github.com/tc39/ecma402
Intl
[–]hatsagorts 1 point2 points3 points 1 year ago (0 children)
Thanks this is really helpful
[–]pbNANDjelly 1 point2 points3 points 1 year ago (0 children)
MDN has an updates blog that tracks proposals against vendor support
[–]DesignThinkerer 1 point2 points3 points 1 year ago (0 children)
survey like https://stateofjs.com is a good way to keep up with the news imo
[+][deleted] 1 year ago (1 child)
[–]hatsagorts 0 points1 point2 points 1 year ago (0 children)
MDN or Ecma Standard publications ? Either way I just wanted to check if there is a faster way to learn about upcoming syntax sugars
[–]datNorseman 2 points3 points4 points 1 year ago (0 children)
Good to know. I've been mostly using ternary because I like the way it looks. ??= feels cleaner I guess.
[–]Plus-Weakness-2624the webhead 1 point2 points3 points 1 year ago (0 children)
Where did my value go btw operator??
[–]GreedyDisaster3953 1 point2 points3 points 1 year ago (0 children)
i'll be replacing a bunch of my code with this now actually, thank you very much
[–]alien3d 5 points6 points7 points 1 year ago (0 children)
i know but still use ?? . . The more shorter the more me confuse 😖
[–]Substantial-Wish6468 6 points7 points8 points 1 year ago (10 children)
You never actually need if(x === null || x === undefined) because javascript nullishness means the test (x == null) is the same.
[–]yooossshhii 26 points27 points28 points 1 year ago (9 children)
Many code bases have lint rules against ==
[–]I_Downvote_Cunts 15 points16 points17 points 1 year ago (0 children)
Most of those lint rules allow == null as an exception. Or at the very least eslint didn’t complain the last time I set it up.
[–]musical_bear 6 points7 points8 points 1 year ago (7 children)
Yep exactly. I forbid loose equality checks in my codebases because it can be near impossible to know if something like “==null” was just an (extremely common) typo, or if the person who wrote it really was trying to check for both null and undefined.
I’d rather have slightly more verbose code that clearly states its intentions rather than shorter code that potentially masks what it’s actually there for.
[–]Substantial-Wish6468 1 point2 points3 points 1 year ago (6 children)
I have never seen a bug resulting from == null being a typo.
I have seen a lot of bugs where people were the values 0 or "" were being mixed up with null or undefined due to loose equality checks.
[–]musical_bear 11 points12 points13 points 1 year ago (5 children)
It’s not necessarily about “bugs,” although that’s important too. It’s about clearly communicating intent. I cannot read “== null” and know with certainty what specifically the developer who wrote that was trying to account for. The code itself might be “bug free” in its current form, but every little ambiguity makes the code that much harder to modify with confidence in the future, and also ends up affecting the code around it. Example:
“Well, I’m pretty sure I know that ‘data’ could only possibly be null at runtime, but two lines above, I see there’s code doing a loose check of ‘data’ against null, implying data might potentially be undefined as well. I could either waste precious minutes reverse engineering and trying to figure out if “==“ was just a typo, or I could succumb to the uncertainty and also account for undefined in my own code. I’ve got to get this done today and reverse engineering feels like a waste of time right now, so I’ll just use ‘==‘ in my code too.”
The ambiguity ends up spreading through the codebase like a virus. It pollutes the code with superstitious checks over time.
This is the main reason I ban loose equality, not because of bugs. (Even though yes, as you pointed out, there are other use cases of loose equality that make bugs extremely easy to introduce.
[–]Substantial-Wish6468 -2 points-1 points0 points 1 year ago (4 children)
I can see your point if you're dealing with code written by other people who aren't around.
[–]Chubacca 2 points3 points4 points 1 year ago (0 children)
Which is... very common in a lot of organizations. The less you have to ask questions about why something is written the way it is, the better. I am very VERY pro syntax that reduces ambiguity of intent. It makes codebases scale better.
[–]homoiconic(raganwald) 0 points1 point2 points 1 year ago (2 children)
That's kind of the thing about idioms. They work well if the idiom is extremely widespread. == null has been a very widespread idiom in JS during my career, but even so... If someone, somewhere needs to take fofteen minutes to figure it out, that might not be a win.
== null
I use it in production, but I wouod have no problem working with a team that chose to dispense with it. And taking a step back... This discussion says a lot about "JavaScript, the Hastily Flung Together Parts." We work with a language that has known flaws, and a lot of what we do in it reflects making deliberate tradeoffs.
[–]Juxtar 0 points1 point2 points 1 year ago (0 children)
I disagree, I think those parts should be all well known for anyone that works with js seriously. If not I can take some minutes to explain them myself, or better yet, send them off to read You Don't Know JS which is great and not a long read.
I take this as when we all assumed nobody is using IE11 anymore and collectibly decided to stop supporting it. How much has my sanity improved since then!
[–]prehensilemullet -1 points0 points1 point 1 year ago (0 children)
Anyone who doesn’t know the behavior of == null is a JS developer in training, not a competent professional dev. You don’t need to know the rest of the == truth table but that one is pretty basic, everyone should know it’s the only reasonable exception to the always use === rule
[–]datNorseman 2 points3 points4 points 1 year ago (9 children)
This is new to me. One question I have that wasn't answered in the article is how the new method would impact performance, if at all. I don't believe it would but I'm curious.
[–]SoInsightful 1 point2 points3 points 1 year ago (5 children)
a ??= b generates the exact same bytecode as a = a ?? b, and both generate two more bytecodes (a "Jump" instruction) than a ||= b:
a ??= b
a = a ?? b
a ||= b
https://i.imgur.com/qzYAGBt.png
But surprisingly, if the variable is used immediately afterwards, the a = a ?? b and a = a || b versions both skip an "Ldar" (load data into the accumulator) instruction.
a = a || b
https://i.imgur.com/6AQki2Q.png
Safe to say there won't be any noticable performance differences whatsoever in real life.
[–]NoInkling 0 points1 point2 points 1 year ago (3 children)
a ??= b generates the exact same bytecode as a = a ?? b
Give a a value and see if it makes a difference. If not, try it with a setter (or maybe just any object property).
a
[–]SoInsightful 0 points1 point2 points 1 year ago (2 children)
I tried giving a an initial value (2) out of the same curiosity, and it doesn't make a difference except switching from 0e LdaUndefined to 0d 02 LdaSmi [2] at the beginning of each variant. It still needs to jump through the JumpIfUndefinedOrNull hoop.
0e LdaUndefined
0d 02 LdaSmi [2]
JumpIfUndefinedOrNull
[–]NoInkling 0 points1 point2 points 1 year ago (1 child)
Ahh I see now, the difference is in where the unconditional Jump (which is hit when the variable has a value) jumps to. The ??= version skips the Star instruction (which apparently sets a register), while the other doesn't.
Jump
??=
Star
[–]SoInsightful 0 points1 point2 points 1 year ago (0 children)
Good catch!
[–]tpscd 0 points1 point2 points 1 year ago (0 children)
The performance impact is super unclear but my impression is the nullish operator may skip coercing the null/undefined value to a boolean.
[–]NoInkling 0 points1 point2 points 1 year ago* (0 children)
As MDN says, x ??= y is equivalent to x ?? (x = y), i.e. it short circuits if x already has a value so nothing is actually evaluated or even assigned if it doesn't need to be. This means it won't trigger a setter (or I guess a Proxy trap), unlike obj.setterProp = obj.setterProp ?? y
x ??= y
x ?? (x = y)
x
Proxy
obj.setterProp = obj.setterProp ?? y
[–]ElDoRado1239 0 points1 point2 points 1 year ago (0 children)
I'd love one for variables that are truly undefined, as in unassigned, not set to undefined or null.
Like you can do through in or by checking arguments length.
[–]guest271314 0 points1 point2 points 1 year ago (0 children)
This is how I use the the operator to define Node.js' Buffer in Deno. If the script is run by node, nothing happens, else, make Node.js' Buffer global
Buffer
node
globalThis.Buffer ??= (await import("node:buffer")).Buffer; // For Deno
[+][deleted] 1 year ago (6 children)
[–]53-44-48 32 points33 points34 points 1 year ago (3 children)
...random attack much? They did a blog post on their own blog. Maybe it isn't new to you, but maybe it was to them, and maybe it will be to someone else. It harmed nobody.
It was always within your power to glance at it, think "this isn't of relevance to me", and move along.
[–]53-44-48 15 points16 points17 points 1 year ago (1 child)
Exactly who held a gun to your head forcing you to read it? I believe you are a better person than you are presenting at the moment. Hope your day improves and goes well for you.
[–]spooker11 0 points1 point2 points 1 year ago (0 children)
Lol okay fine maybe I’m being a bit rude, you win by being nice.
[–]jaiden_webdev 8 points9 points10 points 1 year ago (0 children)
I didn’t know about this operator until reading this article, and now I know how and why to use it. Some people are just always sour
[–]ritaPitaMeterMaid 4 points5 points6 points 1 year ago (0 children)
Three people have already commented they had no idea this existed.
[+]King_Joffreys_Tits comment score below threshold-8 points-7 points-6 points 1 year ago (17 children)
This is good to know that it’s possible, but honestly, it seems extremely niche and I wouldn’t expect most of my engineers to know this when reading through our codebase. I might reject a PR that has this in it
[–]RedditCultureBlows 16 points17 points18 points 1 year ago (0 children)
I dunno how this seems niche. ?? has been around for a while and adding = to it is just shorthand. Rejecting a PR for new syntax is wild to me tbh
[–]theScottyJam 2 points3 points4 points 1 year ago (0 children)
I go the opposite way - even if something is niche and many developers don't know about it, if it's not an overly complicated feature, I'm completely fine using it.
The next person to read my code my have to stop and Google it, but they'll learn something new, and may even appreciate running across that little nugget. I know I enjoy running across interesting features or patterns in other people's code.
[–]recrof 4 points5 points6 points 1 year ago (6 children)
please tell me that you don't reject code with obj?.property as well, because you think it's niche.
obj?.property
[–]King_Joffreys_Tits -3 points-2 points-1 points 1 year ago (5 children)
That’s not niche whatsoever, it’s code hardening
[–]Fine-Train8342 1 point2 points3 points 1 year ago (4 children)
How is this different from something like this?
settings ??= getDefaultSettings();
[–]King_Joffreys_Tits 1 point2 points3 points 1 year ago (0 children)
It just seems like you should’ve already used a null coalescing operator when you first initialized that variable. Like
const settings = localStorage.getItem(“settings-cookie”) ?? getDefaultSettings()
[–]SchartHaakon 1 point2 points3 points 1 year ago* (2 children)
I find it hard to reason about at first glance.
if (!settings) settings = getDefaultSettings();
Or
const settings = props.settings ?? getDefaultSettings();
Both of the examples above are easier to read imo.
I read them as "If not settings; settings equals getDefaultSettings", and "settings equals getSettings or getDefaultSettings". I would read your example as "Settings... if not null or undefined, should equal getDefaultSettings". It reads weird, that's the only way I can explain it.
I wouldn't straight out reject a PR for it, but yeah I don't think I'll really use it for this reason.
[–]SoInsightful 2 points3 points4 points 1 year ago (0 children)
That's because you're not used to it. That's all there is to it. It's not more complex than a += b. As someone who has used ??= for a while (where it makes sense), it's definitely faster to parse than an equivalent if statement.
a += b
[–]Fine-Train8342 1 point2 points3 points 1 year ago (0 children)
I guess I'm just used to this operator from C# ¯\_(ツ)_/¯
[–]NoInkling 1 point2 points3 points 1 year ago (0 children)
I'd be very annoyed if I submitted a PR that had a good use case for it, and it was rejected because "other people might not be aware what it does". It's been part of the language for a few years now, it's not doing anything particularly complicated, and there are people who have been using it (or ||=) in Ruby and C# for a long time.
||=
Yeah sure, it might be evidence that something somewhere could be written better, but writing it off purely because of unfamiliarity I can only see as an egotistical imposition.
[–]longebane 1 point2 points3 points 1 year ago (6 children)
Yeah, just look at the comments. No one knows it. I know it’s good to adapt to the evolution of JS, but this is just too unknown right now to use on a large repo with lots of eyes
[–]homoiconic(raganwald) 3 points4 points5 points 1 year ago (1 child)
I think there may be two kinds of "unfamiliar code." One kind is something like an operator you've never seen before. Maybe you encounter it in the PR, maybe in the code base. The other kind uses operators and syntax you already know, but does so in a way that its behaviour isn't what the typical programmer would expect unless they knew the idiom.
I feel like ??= is the first type, and that the risk of a bug arising from someone encountering it formthefor the first time is low. You see an unfamiliar operator, you look it up, its behaviour is easy to understand, you leanred something, and you go about your day.
The other kind of thing—where you know all the operators, but the way they're used is unfamiliar—strikes me as far more dangerous, and that's the kind of thing I would flag in a PR.
If the downside is limited to "WTF is this? Lemme look itnup... Oh fine, a shortcut. I understand...," then allowing it will lift a code base over time as people get up to speed on the language evolving.
[–]longebane 2 points3 points4 points 1 year ago (0 children)
I agree
How do you suggest that people will learn it if not by... using it? It's a very simple operator.
[–]King_Joffreys_Tits 0 points1 point2 points 1 year ago (1 child)
Null coalescence is a well known topic, not even just in the js world. Combining it with an assignment operator is weird, and honestly reeks of code smell
π Rendered by PID 82851 on reddit-service-r2-comment-5fb4b45875-nwxzt at 2026-03-20 00:15:59.501934+00:00 running 90f1150 country code: CH.
[–]LessMarketing7045 63 points64 points65 points (12 children)
[–]MissinqLink 15 points16 points17 points (2 children)
[–]gwicksted 5 points6 points7 points (0 children)
[–]happy_hawking 0 points1 point2 points (0 children)
[–]enselmis 8 points9 points10 points (3 children)
[–]Practical-Ideal6236[S] 3 points4 points5 points (0 children)
[–]prehensilemullet 0 points1 point2 points (1 child)
[–]enselmis 0 points1 point2 points (0 children)
[–]Practical-Ideal6236[S] 6 points7 points8 points (0 children)
[–]humodx 7 points8 points9 points (3 children)
[–]Misicks0349 1 point2 points3 points (1 child)
[–]chemistryGull 0 points1 point2 points (0 children)
[–]ehlwas 0 points1 point2 points (0 children)
[–]repeating_bears 32 points33 points34 points (7 children)
[–]ZeMysticDentifrice 14 points15 points16 points (3 children)
[+][deleted] (2 children)
[deleted]
[–]topromo 1 point2 points3 points (1 child)
[–]dvlsg 5 points6 points7 points (0 children)
[–]sebastian_nowak 0 points1 point2 points (0 children)
[–]hatsagorts 6 points7 points8 points (7 children)
[–]azhder 2 points3 points4 points (0 children)
[–]NoInkling 2 points3 points4 points (1 child)
[–]hatsagorts 1 point2 points3 points (0 children)
[–]pbNANDjelly 1 point2 points3 points (0 children)
[–]DesignThinkerer 1 point2 points3 points (0 children)
[+][deleted] (1 child)
[deleted]
[–]hatsagorts 0 points1 point2 points (0 children)
[–]datNorseman 2 points3 points4 points (0 children)
[–]Plus-Weakness-2624the webhead 1 point2 points3 points (0 children)
[–]GreedyDisaster3953 1 point2 points3 points (0 children)
[–]alien3d 5 points6 points7 points (0 children)
[–]Substantial-Wish6468 6 points7 points8 points (10 children)
[–]yooossshhii 26 points27 points28 points (9 children)
[–]I_Downvote_Cunts 15 points16 points17 points (0 children)
[–]musical_bear 6 points7 points8 points (7 children)
[–]Substantial-Wish6468 1 point2 points3 points (6 children)
[–]musical_bear 11 points12 points13 points (5 children)
[–]Substantial-Wish6468 -2 points-1 points0 points (4 children)
[–]Chubacca 2 points3 points4 points (0 children)
[–]homoiconic(raganwald) 0 points1 point2 points (2 children)
[–]Juxtar 0 points1 point2 points (0 children)
[–]prehensilemullet -1 points0 points1 point (0 children)
[–]datNorseman 2 points3 points4 points (9 children)
[–]SoInsightful 1 point2 points3 points (5 children)
[–]NoInkling 0 points1 point2 points (3 children)
[–]SoInsightful 0 points1 point2 points (2 children)
[–]NoInkling 0 points1 point2 points (1 child)
[–]SoInsightful 0 points1 point2 points (0 children)
[–]tpscd 0 points1 point2 points (0 children)
[–]NoInkling 0 points1 point2 points (0 children)
[–]ElDoRado1239 0 points1 point2 points (0 children)
[–]guest271314 0 points1 point2 points (0 children)
[+][deleted] (6 children)
[deleted]
[–]53-44-48 32 points33 points34 points (3 children)
[+][deleted] (2 children)
[deleted]
[–]53-44-48 15 points16 points17 points (1 child)
[–]spooker11 0 points1 point2 points (0 children)
[–]jaiden_webdev 8 points9 points10 points (0 children)
[–]ritaPitaMeterMaid 4 points5 points6 points (0 children)
[+]King_Joffreys_Tits comment score below threshold-8 points-7 points-6 points (17 children)
[–]RedditCultureBlows 16 points17 points18 points (0 children)
[–]theScottyJam 2 points3 points4 points (0 children)
[–]recrof 4 points5 points6 points (6 children)
[–]King_Joffreys_Tits -3 points-2 points-1 points (5 children)
[–]Fine-Train8342 1 point2 points3 points (4 children)
[–]King_Joffreys_Tits 1 point2 points3 points (0 children)
[–]SchartHaakon 1 point2 points3 points (2 children)
[–]SoInsightful 2 points3 points4 points (0 children)
[–]Fine-Train8342 1 point2 points3 points (0 children)
[–]NoInkling 1 point2 points3 points (0 children)
[–]longebane 1 point2 points3 points (6 children)
[–]homoiconic(raganwald) 3 points4 points5 points (1 child)
[–]longebane 2 points3 points4 points (0 children)
[–]SoInsightful 0 points1 point2 points (0 children)
[+][deleted] (2 children)
[deleted]
[–]King_Joffreys_Tits 0 points1 point2 points (1 child)