summaryrefslogtreecommitdiff
path: root/doc/guides/using-symbols.md
diff options
context:
space:
mode:
authorMatteo Collina <hello@matteocollina.com>2018-09-04 12:10:01 +0200
committerDaniel Bevenius <daniel.bevenius@gmail.com>2018-09-07 09:23:03 +0200
commit4f5aa3607d84ad500e496fbffccd91b769cab259 (patch)
tree0817badf02830432d252f908d5fe28fb5d636d0a /doc/guides/using-symbols.md
parenta1a0c5906338c62eeb4c9f3b9ee094862ec02dad (diff)
downloadandroid-node-v8-4f5aa3607d84ad500e496fbffccd91b769cab259.tar.gz
android-node-v8-4f5aa3607d84ad500e496fbffccd91b769cab259.tar.bz2
android-node-v8-4f5aa3607d84ad500e496fbffccd91b769cab259.zip
doc: added symbols guidelines
PR-URL: https://github.com/nodejs/node/pull/22684 Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com> Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Diffstat (limited to 'doc/guides/using-symbols.md')
-rw-r--r--doc/guides/using-symbols.md73
1 files changed, 73 insertions, 0 deletions
diff --git a/doc/guides/using-symbols.md b/doc/guides/using-symbols.md
new file mode 100644
index 0000000000..1e79e1a4e4
--- /dev/null
+++ b/doc/guides/using-symbols.md
@@ -0,0 +1,73 @@
+# Using global symbols
+
+ES6 introduced a new type: `Symbol`. This new type is _immutable_, and
+it is often used for metaprogramming purposes, as it can be used as
+property keys like string. There are two types of
+symbols, local and global.
+Symbol-keyed properties of an object are not included in the output of
+`JSON.stringify()`, but the `util.inspect()` function includes them by
+default.
+
+Learn more about symbols at
+https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Symbol.
+
+## `Symbol(string)`
+
+Symbols created via `Symbol(string)` are local to the caller function.
+Note that `Symbol('hello') !== Symbol('hello')`.
+For this reason, we often use them to simulate private fields, like so:
+
+```js
+const kField = Symbol('kField');
+
+console.log(kField === Symbol('kField')); // false
+
+class MyObject {
+ constructor() {
+ this[kField] = 'something';
+ }
+}
+
+module.exports.MyObject = MyObject;
+```
+
+Note that Symbols are not _fully private_, as the data could be accessed
+anyway:
+
+```js
+for (const s of Object.getOwnPropertySymbols(obj)) {
+ const desc = s.toString().replace(/Symbol\((.*)\)$/, '$1');
+ if (desc === 'kField') {
+ console.log(obj[s]); // 'something'
+ }
+}
+```
+
+Local symbols make it harder for developers to monkey patch/access
+private fields, as they require more work than a property prefixed
+with an `_`. Monkey patching private API that were not designed to be
+monkey-patchable make maintaining and evolving Node.js harder, as private
+properties are not documented and can change within a patch release.
+Some extremely popular modules in the ecosystem monkey patch some
+internals, making it impossible for us to update and improve those
+areas without causing issues for a significant amount of users.
+
+## `Symbol.for`
+
+Symbols created with `Symbol.for(string)` are global and unique to the
+same V8 Isolate. On the first call to `Symbol.for(string)` a symbol is
+stored in a global registry and easily retrieved for every call of
+`Symbol.for(string)`. However, this might cause problems when two module
+authors use the same symbol
+for different reasons.
+
+```js
+const s = Symbol.for('hello');
+console.log(s === Symbol.for('hello'));
+```
+
+In the Node.js runtime we prefix all our global symbols with `nodejs.`,
+e.g. `Symbol.for('nodejs.hello')`.
+
+Global symbols should be preferred when a developer-facing interface is
+needed to allow behavior customization, i.e., metaprogramming.