Skip to content

Instantly share code, notes, and snippets.

@tmcw
Created October 12, 2017 18:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tmcw/ec339185d0186b96e2ab5ed9a959273c to your computer and use it in GitHub Desktop.
Save tmcw/ec339185d0186b96e2ab5ed9a959273c to your computer and use it in GitHub Desktop.
Some things I've learned about devtools recently

THE INSPECTION UNCERTAINTY PRINCIPLE

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] }

THE NATIVE ADVANTAGE

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.

DISPLAYING FUNCTIONS IS KIND OF TERRIBLE

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.

BOXED LITERALS: WTF!

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment