Skip to content

Instantly share code, notes, and snippets.

@danielmascena
Forked from paulirish/gist:4158604
Created December 7, 2012 16:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danielmascena/4234521 to your computer and use it in GitHub Desktop.
Save danielmascena/4234521 to your computer and use it in GitHub Desktop.
Learn JavaScript concepts with recent DevTools features

Learn JavaScript concepts with the Chrome DevTools

Authored by Peter Rybin , Chrome DevTools team

In this short guide we'll review some new Chrome DevTools features for "function scope" and "internal properties" by exploring some base JavaScript language concepts.

Closures

Let's start with closures – one of the most famous things in JS. A closure is a function, that uses variables from outside. See an example:

function A(a, b, c) {
  var ar = [a, b, c];
  return function B(i) {
    return ar[i];
  };
}

var b = A('Here', 'I', 'am');
console.log( b(1) );

The first statement calls A that creates local array, returns function B (saved in variable b) and finishes.

The second statement calls function B (b) that returns an array item. That means that array ar from A has remained existing since A finished. But where was it stored? Of course, in b! But how exactly? In some property maybe? No. It's a core language feature, that a function can bear outside variables and there is no other way to access them but calling the function.

From now on, the debugger makes it explicitly visible. Get a function instance b from the example above and expand its properties. A sub-node called <function scope> should be there. It's where values of all bound variables will be shown. Those are the variables the function will use when called.

Internal properties

The other thing that DevTools debugger now shows is internal properties.

Suppose your code got a value s and does the following operation:

s.substring(1, 4)  // returns 'ell'

Do you think that s is a string? Not necessarily. It also can be a string object wrapper. Try the following in watch expressions:

"hello"
Object("hello")

First is a regular string value, the second is a full-featured object. As confusing as it could be, the two values behave almost identically. But the second one has real properties and you can set your own too. Expand the properties list and you will notice, how it's not a completely regular object: it will have an internal property [[PrimitiveValue]] , where the original string value is stored. You cannot access this property from your code, but you can see it in DevTools debugger now.

Who else has internal properties? It's bound functions. This is also a sort of wrapping, but for functions. Try executing these 2 statements:

function Sum(a, b) { return a + b; }
var inc = Sum.bind(null, 1); // binds a=1

If you put Sum and inc in watch expression section and compare them, you'll learn, that both are functions. But inc is a non-transparent one: you cannot see neither its text nor open its declaration, much unlike Sum.

That's how bound functions work. However, since now all the necessary data is shown in debugger as internal properties: among other properties of 'inc' (not very interesting), you will find [[BoundTarget]], [[BoundArgs]] and [[BoundThis]]. They indicate that inc is a bound function first of all, and also it tells you all about it: that is wraps Sum function, binds first argument with value 1 and passes null as this.

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