-1

The "nullish-coalescing assignment" operator, ??=, is a relatively recent introduction to JavaScript; but not all that recent... and yet, eslint, even newer versions like 8.38.0, seem not to recognize it - and yields a syntax error about the assignment (the = after the ??). Here's the line I'm trying to get to pass the check:

var ObjectUtils  ??=  ChromeUtils.import("resource://gre/modules/ObjectUtils.jsm").ObjectUtils;

Why is this happening? And - how can I tell eslint to accept this operator?

einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • Try using ECMAScript 2021 in the config? `{ "parserOptions": { "ecmaVersion": 2021 } }` seems to remove the error for me – evolutionxbox Apr 24 '23 at 14:21
  • I can't reproduce the problem. Picking the most restrictive options from the eslint configuration wizard and running it against the Try It example on the MDN page you link to, it complains only about `console.log`. You should provide a [mcve], including your eslint configuration and the lines of package.json that provide eslint and its plugins (for the specific versions). – Quentin Apr 24 '23 at 14:23

1 Answers1

1

You need to make sure ecmaVersion is set to "latest" or to 2021 (aka 12) or higher, so ESLint knows what version of JavaScript to parse (more in the configuration help). Here's an ESLint playground example using ??= successfully with the version set to "latest"; here's one where it doesn't work because the version is set to 2020.


Re your update showing this code:

var ObjectUtils ??= ChromeUtils.import("resource://gre/modules/ObjectUtils.jsm").ObjectUtils;

...it's not an ESLint or ??=-specific thing, that's just not a valid place to use a compound assignment operator (any of them). Here's an example using += in JavaScript (no linter):

var a += 42;
//    ^−−−−−−−− SyntaxError: Unexpected token '+='
console.log(a);

In the normal case, you'd just want an assignment operator (ideally using let or const; var shouldn't be used in new code):

let ObjectUtils = ChromeUtils.import("resource://gre/modules/ObjectUtils.jsm").ObjectUtils;

In a very unusual situation where you had to declare a variable that might already be declared and use its current value if it's not nullish, you'd have to separate that into two parts:

// **VERY** rare use case, there are better options
var ObjectUtils; // Possibly a redeclaration
ObjectUtils ??= ChromeUtils.import("resource://gre/modules/ObjectUtils.jsm").ObjectUtils;

But I wouldn't do that in new code. :-)

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • *(Doh! Typo, if you see "2021" at the very end instead of "2020", hit refresh)* – T.J. Crowder Apr 24 '23 at 14:23
  • So, that itself didn't work for me, but I figured out it was because I had `var` at the beginning of the line, so perhaps you can update your answer accordingly. – einpoklum Apr 24 '23 at 14:28
  • @einpoklum - Done. Was that just a mistake or was there something you were trying to do with that combination of `var` and `??=`? – T.J. Crowder Apr 24 '23 at 14:36
  • @einpoklum Normally when you use `var`, `let` or `const` it means that the variable isn't defined yet. So the value must always be non-existent. This makes the use of `??=` in the same statement very strange, since you know that there is nothing there. `var` is a bit special, since it allows re-definitions without throwing errors, but in normal scenarios `var` is only used once to define (and assign) the value. – 3limin4t0r Apr 24 '23 at 14:59
  • 1
    If you use it in global scope consider `window.ObjectUtils ??= ...` instead of using `var`. – 3limin4t0r Apr 24 '23 at 15:07
  • @T.J.Crowder: I wanted to ensure that a global was defined. Before, my code has `if (typeof ObjectUtils == 'undefined' ) { var ObjectUtils = whatever; }`, and that gave me a linting error, so I tried rewriting it using ??= . But may 3liminator's approach is what I should really do. – einpoklum Apr 24 '23 at 15:10
  • 1
    @einpoklum - Yeah, or using `globalThis` instead of `window` nowadays. (That said: I'd suggest adopting modules as soon as convenient. :-) ) – T.J. Crowder Apr 24 '23 at 15:20
  • @T.J.Crowder: I thought I had adopted modules... T_T ... I'm just importing some modules and using a global as a shorthand for them. I realize this could be very wrong, I don't really know JS, I just write some occasionally, whenever Thunderbird breaks my extensions. – einpoklum Apr 24 '23 at 18:26
  • @einpoklum - I should have been more clear, sorry. I meant "modules" in the specific [JavaScript module syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) sense, not the more general sense. When using real modules, you don't need globals. – T.J. Crowder Apr 24 '23 at 19:16