Last active
February 23, 2018 23:09
-
-
Save abstractmachines/18ea0dc6b8b98e307e937806b772f974 to your computer and use it in GitHub Desktop.
Well Known Symbols : instanceof via custom Symbol.hasinstance
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Well Known Symbols : Symbol.hasinstance | |
sources: | |
1 - https://www.keithcirkel.co.uk/metaprogramming-in-es6-symbols/ | |
2 - http://exploringjs.com/es6/ch_symbols.html | |
3 - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof | |
4 - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/hasInstance | |
Well Known Symbols are Reflection via implementation in ES6. | |
Reflection in Metaprogramming: observing low level internals of a programming language/program. | |
One example of Well Known Symbols in JS is Symbol.hasInstance, which instanceof uses under the hood. | |
*/ | |
// using instanceof : | |
function ClassyFunc() {} | |
let c = new ClassyFunc(); | |
if (c instanceof ClassyFunc) { | |
console.log('instanceof.') | |
} | |
else { | |
console.log('not instanceof.') | |
} | |
// > instanceof | |
/* Let's implement that by hand. | |
Under the hood, instanceof uses (rhs)[Symbol.hasInstance](lhs), | |
where rhs is right hand side and lhs is left hand side. | |
Symbol is static scoped. | |
*/ | |
class ArrayClass { | |
static [Symbol.hasInstance](input) { | |
return Array.isArray(input) | |
} | |
} | |
let a = [] | |
let b = 3 | |
console.log(a instanceof ArrayClass) | |
// > true | |
console.log(a instanceof ArrayClass) | |
// > false |
Instanceof lies. Typing matters
https://medium.com/@_ericelliott/javascript-does-not-have-static-types-69492ce923b5
"JavaScript does not have static types. What you’re asking for does not exist in the language.
Therefore there is no way to do a static type check that you can rely on in JavaScript.
That’s why instanceof lies and can be the source of lots of bugs or awkward restrictions.
Nominal types (type checking based on the name or identity of a single class/interface)
will never work well in JavaScript.
That’s why TypeScript (which adds static annotations and analysis on top of JavaScript) uses structural types,
which is basically automated duck typing."
- Eric Elliott
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
There are many well known symbols
There are other "well known symbols" that are the implementation, under the hood, of JS functions.
For example,
for of
usesSymbol.iterator
under the hood (somewhere in the prototype chain, one of the objects in that chain has an @@iterator; each time thefor of
is used,Symbol.iterator
is invoked). More info on MDN.Symbols are not the best choice for information hiding
The argument has been made that Symbols can be used for information hiding/encapsulation in JS, but that is not a complete encapsulation, as getters for Symbols/Reflect can still be used to access that data. See Dr Rauschmeyer's blog on information hiding with JS here - generally, using the Constructor or WeakMaps are preferred. Here's another blog post detailing how Firefox dev tools used WeakMaps for information hiding (encapsulation).