top | item 28378351

ES2022 feature: class static initialization blocks

23 points| ingve | 4 years ago |2ality.com | reply

63 comments

order
[+] simias|4 years ago|reply
I've had the displeasure of having to write quite a bunch of JS over the past few years (I'm mainly a system programmer usually). I do think that the JS "standard library" is ridiculously under-featured and makes dealing with even basic arrays or objects much more painful than it needs to be. It's been improving of late but it's baffling to me that it took so long to have something like Object.values() for instance.

That being said I never though that JS was really lacking syntax-wise. "Arrow functions" are a nice shorthand for sure, and "let" should really have been there from the start, but this addition of classes feels really unnecessary and redundant. It just creates more ways to do things you could already do, without obvious benefits and the obvious drawback of making the language more complex.

Since nowadays transpilation is so common place, what even is the point? You already have a rather large selection of other languages to use if you don't like raw JS.

I'm all for improving the existing JavaScript language but that just looks like tacking on a completely different language on top of it in order, I assume, to make it look more familiar for Java/C# coders?

[+] eatonphil|4 years ago|reply
The biggest thing stopping me from using other compile-to-Javascript languages is that almost none of them fully support async-await.

Many of them have some support for async/await but few can handle all cases such as async-await within try-catch and so on.

Scala.js async-await is not part of the standard libary I think and has this limitation: https://github.com/scala/scala-async#limitations.

Kotlin.js might support async-await but I find their JavaScript documentation so confusing/non-existent I can't tell. But also, Kotlin is too similar to JavaScript already anyway. It doesn't have ML-style pattern matching for example.

The Java-to-JavaScript and C#-to-JavaScript compilers both are too underused as far as I can tell. The latter, Blazor, is too focused on ASP.NET for me to be able to understand if I could write it the way I write React apps.

Elm, ReScript, and other ML/Haskell-influenced languages are too niche even though I'm a big Standard ML fan.

I'm not sure what else there is to look at.

And I really don't want to go back to using promises and callbacks.

[+] vbezhenar|4 years ago|reply
They invented syntax instead of library functions. You don't need array prepend/append functions, when you can write [item1, ...arr, item2]. Some of those syntaxes are quite elegant and I miss those in other languages.
[+] tragomaskhalos|4 years ago|reply
100%. No one dislikes progress, but the JavaScript world is really something else. I have Flanagan's "JavaScript: the definitive guide" 6th edition (that '6' is already a red flag), which predates so many changes in the language that it's essentially an expensive doorstop now. I think of all my technical books probably only the COM and J2EE ones have aged as badly, and yet I bought the Flanagan far more recently than any of those hoary old tomes.
[+] amitport|4 years ago|reply
Yes, junior devs and (and students) "get" classes much better than they do prototypes. This is a Hugh win when you care about productivity.

(Also note, => is not just a different syntax for function)

[+] puppet-master|4 years ago|reply
Death by a thousand features. Very happy to see all the tons of new library work over the years, but really detest pretty much all new syntax extensions, it's morphed JS into the very thing it was never intended to be.

2006 era JS was more than sufficient to build out highly maintainable 100k+ LOC codebases, all this stuff does is introduce new variations of the same functionality for almost no benefit. Javascript is no longer a small language. I think the only surviving practical small language is Lua, and it's only remained small because the hoards are yet to turn up and bulldoze its original design with infinite feature requests

[+] tasogare|4 years ago|reply
> 2006 era JS was more than sufficient to build out highly maintainable 100k+ LOC codebases

Typescript wouldn't have been created if this was the case.

[+] ludamad|4 years ago|reply
It would be nice to have another long feature freeze with languages adding features on top of JavaScript again. That seemed like a great way for ideas to stew for a while - I went from 'oh finally' on new JS features to 'oh ok'
[+] arcbyte|4 years ago|reply
Why are we slowly turning javascript in java? This seems like a secret Oracle plot
[+] snorremd|4 years ago|reply
Indeed. JavaScript was supposed to be scheme with its own object property inheritance model. Of course stakeholders co-opted the language and forced the Java style syntax (and name) upon the language. Now most of the syntax additions has been focused on turning it into some kind of C#/Java lookalike so people who don't like functional programming and the object paradigm used in JavaScript can pretend it's just like the OOP stuff they like.

Instead of trying to turn JavaScript into C#/Java, C# and Java should just support compiling to web assembly and provide a good standard library for working with browsers. /rant

[+] nerdponx|4 years ago|reply
I suspect it's because frontend web developers are jealous of other people using and interesting variety languages, so they want to incorporate as many features from those other languages as possible in order to feel like they are getting some variety themselves.

I don't blame them. That's exactly how I would feel!

That, or, it's easier to upgrade to a new JS version + let your transpiler figure it out, than to rewrite your code in some other language that compiles to JS.

[+] cygned|4 years ago|reply
I find Java code way more maintainable than JavaScript or TypeScript, to be honest. Especially since Java 11, the language has evolved significantly.
[+] junon|4 years ago|reply
Yep, the fact that TC39 seems to accept just about anything is really concerning to me.

I'm already fighting with people about integer literal separators not being supported in e.g. Vue and stuff, the more that's added, the more the community becomes fragmented, and I'm not convinced that transpiration (I hate that word...) is really paying off for us after all these years.

[+] lcam84|4 years ago|reply
I loved the "good parts” of JS back in 2010. I think I don't need most of this new syntax and yet sometimes have the feeling I'm losing the train when I see this “C#” code base. Curiously, that was the technology I used to work before.
[+] eatonphil|4 years ago|reply
Does JavaScript have regular blocks? There are a number of times where I want to put a small amount of local logic in a block without having to put into an anonymous function called immediately and without moving that logic further up in code.

A specific example of this is doing some small custom callback logic in d3 configuration.

    foo: {
      const f = 1;
      f
    }
Versus:

    foo: (() => {
      const f = 1;
      return f;
    })() 
Blocks are common in other expression-oriented languages like Scheme, Ruby, Rust, and Standard ML. I would like to be able to use that in JavaScript.
[+] nicoburns|4 years ago|reply
It does, but they aren't expressions like you're suggesting. They only thing they do is limit the scope of variable defined inside them (assuming let or const are used. var is not effected). There is a proposal for this under the name "do expressions" because the proposed syntax is like this:

    foo: do {
      const f = 1;
      f
    }
(because a plain block would be ambiguous with object literal syntax in some cases).
[+] twhb|4 years ago|reply
Kind of.

    let x

    _: {
        let y = 1
        let z = 2
        x = y + z
    }

    y // <- throws
[+] tnzm|4 years ago|reply
So, this, but with more steps?

    function Foo () {
      var x = 1 // "static initialization block"
      return {
        y: 2,
        z: function () { return x + y }
      }
    }
    const foo = Foo()
There's been exactly zero need for the "class" keyword, "constructor()", or that new "#private" thing.

There is one flaw in the design of the language which opens the door to all this nonsense; that's having to write "foo.method.bind(foo)" instead of just "foo.method" when passing "method" as a callback, in order to preserve the value of "this". Although in the example above this is not a problem, as you can write functional code that passes the context explicitly without needing "this".

Another thing I wish JavaScript had kept was the "with" statement.

[+] cabalamat|4 years ago|reply
> Another thing I wish JavaScript had kept was the "with" statement.

Consider the following:

    with (a) {
        with (b) {
            with (c) {
                d = e;
            } 
        }
    }
Does this mean:

(1) a.b.c.d = e

(2) d = a.b.c.e

(3) something else

(4) it's impossible to tell?

Correct answer: (4) it's impossible to tell!

One of the worst things about programming is looking at someone else's code (or worse, one's own code) and thinking "WTF did they mean by that?". And that's why I don't like the with statement.

[+] lifthrasiir|4 years ago|reply
> that new "#private" thing

I can agree that classes have been more or less a syntactic sugar, but private identifiers are not. The field name collision is a problem in virtually every dynamically typed language with namespace inheritance and each language has their solutions (see Python `__mangled_name` and Ruby `@instance_var`), JavaScript just happens to have another solution and that alone justifies a separate `class` syntax (since the scope of such private identifiers should be lexical).

[+] tmpfs|4 years ago|reply
Arrow functions replace the need to use `bind` and you can still use `with` just not in strict mode unfortunately.
[+] mirekrusin|4 years ago|reply
We just need pattern matching and js/ts is going to be very nice language to use.
[+] junon|4 years ago|reply
Typescript is not Javascript. TS is a language maintained by Microsoft and happens to compile to Javascript but doesn't have to.

Thus, TS should not have any influence over how JS evolves, but unfortunately that ship has sailed it seems.

[+] twhb|4 years ago|reply

    class Foo {}
    const r = func()
    Foo.prop1 = r.prop1()
    Foo.prop2 = r.prop2()
What am I missing? Why do we need all these new syntaxes?
[+] tnzm|4 years ago|reply
Three words: embrace, extend, extinguish.
[+] drenvuk|4 years ago|reply
That proposal is ugly. I'd rather just use:

    class Translation{
        static get translations(){
            return {blah: things};
        }
        static englishWords(){ return Object.keys(this.translations);}
    }
Since it's all static can't browsers optimize what's already there in this case? I feel like I'm missing something.
[+] inbx0|4 years ago|reply
There's an observable difference with your getter based approach and the "normal property values" approach in the article:

    const t = new Translation
    // property value that
    // is initialized once
    t.translations === t.translations
    // getters which return
    // new objects
    t.translations !== t.translations
so at the very least the browser can't optimize that behavior away, it needs to create new objects. Besides, ensuring that say, call to `Object.keys` is side-effect free is challenging.
[+] dzonga|4 years ago|reply
the author, thanks to him. has put out a lot of material to gain deep knowledge in javascript. I love js and it has put food on the table. but it's becoming a difficult language to learn / keep up with for people with preference for small languages. yeah ES+ features are beneficial sometimes but adding new syntax just keeps folks on the hamster wheel. python suffers this problem as well, that my pleasure in writing python was in the python 2 days.

I have started migrating from those platforms to ruby / clojure. since things rarely get added to those ecosystems. one can pop in after 20 years and nothing has changed and everything still works as before

[+] greydius|4 years ago|reply
> one can pop in after 20 years and nothing has changed

20 years ago Clojure didn't exist and Ruby was practically unknown outside of Japan

[+] cutler|4 years ago|reply

    JS in Spring
    Lotus blossoms
    Java clouds rain
    All is lost
[+] qudat|4 years ago|reply
I dont get why we need this. I actively avoid classes in JS and dont really see the need for static blocks. Its something Ive never needed.

Id like to see more functional programming concepts implemented before more OOP.

[+] simion314|4 years ago|reply
>I actively avoid classes in JS

JS has things like String,Number,Date why not use classes to create your own stuff (say Customer,Product, Transaction) and have your pure functions operate and return well defined objects - for sure it helps with readability and maintainability.

[+] riho|4 years ago|reply
Meanwhile, we still don't have operator overloading. Even Lua has it.
[+] yakshaving_jgt|4 years ago|reply
This makes me sad. All of these added features mean it's increasingly hard for more junior developers to break into this industry. The market essentially dictates that juniors learn JavaScript. The status quo of poor interviewing practices is such that juniors are forced to memorise curious quirks of the language, rather than focus on the essentials (like in JS: The Good Parts) to be productive.