4 ms·
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 w
by vaylian 1y ago
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.
- Kalabasa 1y agoObject 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]()
- TheRealPomax 1y agopretty sure they were asking about the dynamic property name, { [thing]: ... }
- homebrewer 1y agohttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#computed_property_names 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.
- deleted 1y ago[deleted]
- MrJohz 1y agoDynamic 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.
- cluckindan 1y agoIt’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"
- MrJohz 1y agoThat'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.
- ff2400t 1y agoThis 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.
- zdragnar 1y agoDynamic 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-name-with-es6/ 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/ 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.
- a4isms 1y agoYes, 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/Reference/Global_Objects/Symbol/iterator https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
- 90s_dev 1y agoconst o = {} o["foo"] = function(){} o["foo"]() let key = "foo" o[key]() key = Symbol.dispose ?? Symbol.for('dispose') o[key]() o[Symbol.dispose]()
- mceachen 1y agoOther 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.
- whizzter 1y agoThis is the most important reason!
- paulddraper 1y agoThat'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.
- vaylian 1y ago> 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?
- masklinn 1y ago[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