Yes, this will be familiar to people creating objects or classes that are intended to represent iterable collections. You do the same dynamic key syntax with a class declaration or object literal, but use `Symbol.iterator` as the well-known symbol for the method.
Other posters correctly described _what_ this is, but I didn't see anyone answer _why_.
Using a Symbol as the method name disambiguates this method from any previously-defined methods.
In other words, by using a Symbol for the method name (and not using a string), it's impossible to "name collide" on this new API, which would accidentally mark a class as disposable.
The premise is that you can always access an object's properties using indexing syntax as well as the normal dot syntax. So `object.foo` is the equivalent of `object["foo"]` or `object["f" + "o" + "o"]` (because the value inside the square brackets can be any expression). And if `object.foo` is a method, you can do `object.foo()` or `object ["foo"]()` or whatever else as well.
Normally, the key expression will always be coerced to a string, so if you did `object[2]`, this would be the equivalent of object["2"]. But there is an exception for symbols, which are a kind of unique object that is always compared by reference. Symbols can be used as keys just as they are, so if you do something like
You should see in the console that this object has a special key that is a symbol, as well as the normal "foo" attribute.
The last piece of the puzzle is that there are certain "well known symbols" that are mostly used for extending an object's behaviour, a bit like __dunder__ methods in Python. Symbol.dispose is one of these - it's a symbol that is globally accessible and always means the same thing, and can be used to define some new functionality without breaking backwards compatibility.
I hope that helps, feel free to ask more questions.
That's also possible, and it's common when using this pattern, but the specific syntax in the original question was I believe property access, and not part of a property literal. I didn't bring that up because I thought my comment was long enough and I wanted to explain that specific syntax. But yeah, you also have this syntax to set properties in object literals, and a similar syntax in classes.
`obj[Symbol.dispose]()` is the same as `[Symbol.dispose]()`? That doesn't seem right, because we might also have `obj2` or `obj3`. How does JavaScript know that `[Symbol.dispose]()` refers to a specific object?
[Symbol.dispose] is a way of creating an entry whose key is the value of the expression Symbol.dispose in the same way obj[Symbol.dispose] is a way of accessing it.
The parens are just the method definition shorthand, so it’s a shorter way of writing
[Symbol.dispose]: function()
Bracketing was introduced because Javascript was originally defined to use bare keys so
foo: bar
Defines an entry with the key `”foo”`, rather than an entry whose key is the value for the variable `foo`. Thus to get the latter you use
[Symbol.dispose]()
is very weird in my eyes. This looks like an array which is called like a function and the array contains a method-handle.
What is this syntax called? I would like to learn more about it.