Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I understand that JavaScript needs to maintain backwards compatibility, but the syntax

[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.



Dynamic keys (square brackets on the left hand side in an object literal) have been around for nearly 10 years, if memory serves.

https://www.samanthaming.com/tidbits/37-dynamic-property-nam...

Also in the example is method shorthand:

https://www.samanthaming.com/tidbits/5-concise-method-syntax...

Since symbols cannot be referred to by strings, you can combine the two.

Basically, there isn't any new syntax here.


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.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...


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.


This is the most important reason!


Dynamic property access perhaps?

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

    const obj = {}
    obj.foo = "bar"
    obj[Symbol("foo")] = "bar"
    console.log(obj)
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.


It’s not that, it’s a dynamic key in an object literal.

    const key = "foo";
    const obj = { [key]: "bar" };
    console.log(obj.foo); // prints "bar"


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.


https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

Someone more knowledgeable will join in soon, but I'm pretty sure it was derived from:

  const x = { age: 42 };
  x[Symbol.name] = "joe"; // <--- this
so it makes a lot of sense.


This syntax has been used for quite some time. JavaScript iterator use the same syntax and they been part of JavaScript for almost a decade now.


  const o = {}
  o["foo"] = function(){}
  o["foo"]()
  let key = "foo"
  o[key]()
  key = Symbol.dispose ?? Symbol.for('dispose')
  o[key]()
  o[Symbol.dispose]()


That's a notational reference to a functional.

If the code is

  obj.function()
they are notating it as `function()`.

If the code is

  obj[Symbol.dispose]()
they are notating it as `[Symbol.dispose]()`.

Symbol.dispose is a symbol key.


> If the code is

> obj[Symbol.dispose]()

> they are notating it as `[Symbol.dispose]()`.

So

`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

    [foo]: bar


Object property access i guess. Like

myObj["myProperty"]

If it's a function then it could be invoked,

myObj["myProperty"]()

If the key was a symbol,

myObj[theSymbol]()


pretty sure they were asking about the dynamic property name, { [thing]: ... }




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: