You might think about looking at values and executing code as kind of separate things! And I did too, with few exceptions. There are some exceptions - some obvious and some less obvious: for instance:
Iterators: you can't look at an iterator's values unless you iterate over it, and you can't "reset" an iterator, so you can't really inspect it - EXCEPT FOR ONE EXCITING CAVEAT COVERED IN THE NEXT SECTION
Gettters: objects in JavaScript can have 'getters', like
const x = { get x() { throw new Error('hi'); } }
If you were to just 'look at the value', you'd trigger an error! You also might trigger some sort of side effect), changing the value that you just wanted to inspect. This is why the Chrome web inspector will show this object like
{}
x: (...)
And the node inspector will show it as
{ x: [Getter] }
Here's that caveat! So, if you try to inspect an iterator in Chrome DevTools, it'll actually show you what's in it!
(new Map([[1, 1]])).entries()
▶ MapIterator {1 => 1}
HOW! Well, Chrome is connected directly to V8: it isn't really in 'userland' so to speak. Same with Node - both have access to slots - internal data representations in JavaScript. We - writing applications in browsers - don't have access to slots, unless we implement a JavaScript-in-JavaScript interpreter to get ultimate power at the expense of everything being slow and difficult.
How do you differentiate between an arrow function and a function declaration? If you're node or Firefox, well, you don't! In their inspectors, that quality of a function is ignored. The only way to reliably tell if something is an arrow function in JavaScript is to stringify it and test that representation:
(() => {}).toString()
"() => {}"
Firefox doesn't even differentiate between functions and generator functions - even though that's easier to test, by checking whether a function's prototype is the same as the prototype of another generator function.
How do you display this:
new String('hi');
If you're Chrome, you choose a pretty weird rep!
String {0: "h", 1: "i", length: 2, [[PrimitiveValue]]: "hi"}
Which is, well, sort of accurate! But weird, right? Boxed literals are a very weird corner of JavaScript: my mysterious(ly awesome) jsonlint-lines project, which is the magic behind geojsonhint uses boxed literals so that it can assign properties to strings and boolean values.