3

As an option since Chrome 68 (enabled by default since Chrome 72 or perhaps earlier), the DevTools console does as-you-type "eager evaluation" result preview for certain expressions.

For example, if you type in

encodeURIComponent(document.querySelector('.top-bar .-logo').innerHTML);

You get a pink preview of

"%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%20class%3D%22-img%20_glyph%22%3EStack%20Overflow%3C%2Fspan%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20"

below, without hitting Enter.

This does not work, however, for, say

document.querySelector('.top-bar .-logo').href;

and (as would be expected) it doesn't work with expressions that contain loops.

Is it documented somewhere exactly which expressions will work with this and which won't? The initial announcement of the feature mentions

DevTools does not eager evaluate if the expression causes side effects.

but that doesn't seem to explain why it would work for .innerHTML but not .href.

What, exactly, determines which expressions it will attempt to evaluate?

Jacob C.
  • 345
  • 1
  • 16
  • 1
    That's the ["Eager evaluation"](https://developers.google.com/web/updates/2018/05/devtools#eagerevaluation). You can turn it on and off from your console's settings panel (the little gear icon at top right of the console area) – Kaiido Mar 27 '19 at 03:11
  • You've identified the name of the behavior, but that's not what I was asking for. Neither the [update note link](https://developers.google.com/web/updates/2018/05/devtools#eagerevaluation) nor answers to the question that you've (wrongly) marked it as duplicate of actually explain why, to repeat my example, .innerHTML works, while .href doesn't. The updates note *does* say it won't evaluate if it causes [side effects](https://stackoverflow.com/questions/8129105/javascript-closures-and-side-effects-in-plain-english-separately/8129277#8129277) but how does getting .href cause side effects? – Jacob C. Mar 27 '19 at 19:55
  • Sorry I misinterpreted your question. Would you mind [edit] it to make it clear what you are after (e.g you could use the correct terminology, and not link to that page which doesn't document at all this feature, but unrelated ones). I then would be very fine to reopen it. And for how can `.href` cause side effects, well, it's actually a getter function, so it may have side effects (but just like innerHTML, so they might indeed have a white-list, and even a broken one since they do eager some properties like `offsetTop` which **do** have side effects. – Kaiido Mar 28 '19 at 00:50
  • Fair enough. Edited to clarify. – Jacob C. Apr 01 '19 at 17:51

1 Answers1

5

They make use of a quite complex whitelist system, that can be found here.

Basically, they have some built-ins that are marked as safe, and walk through all the internals of the expression, exiting as soon as they don't know if something is safe or not.

As for an explanation of why the two expressions you gave didn't produce the same result... That might be quite complicated.
But we can already note that both are getters, and thus will both call an internal function in order to return the computed value. This getter function can itself run some code that will have some side-effects.

For instance

const o = {
  _count: 0,
  get count() { return this._count++; }
};

From there, evaluating o.count would increment the _count property, and thus this getter is marked as unsafe.

Now, I have to admit I am not sure what .href internally calls, and why this algo will mark it as unsafe, but clearly, there is something... And if you absolutely want to know what it is, then you may want to check document.baseURI internals which must be called from .href and which is itself marked as unsafe.

Kaiido
  • 123,334
  • 13
  • 219
  • 285
  • 1
    It also uses a large blob of generated code [https://cs.chromium.org/search/?q=innerhtml.*sideeffect](https://cs.chromium.org/search/?q=innerhtml.*sideeffect) as a lookup table … innerHTML is marked as a getter with no side effects, but href is not. getAttribute is safe, though. – Josh Lee Apr 02 '19 at 12:28
  • 1
    Indeed, all the various flavors of HTMLWhateverElement and their probably hundreds of getters are absent from this list. – Josh Lee Apr 02 '19 at 12:30