What Is Lexical Scope

What is lexical scope?

I understand them through examples. :)

First, lexical scope (also called static scope), in C-like syntax:

void fun()
{
int x = 5;

void fun2()
{
printf("%d", x);
}
}

Every inner level can access its outer levels.

There is another way, called dynamic scope used by the first implementation of Lisp, again in a C-like syntax:

void fun()
{
printf("%d", x);
}

void dummy1()
{
int x = 5;

fun();
}

void dummy2()
{
int x = 10;

fun();
}

Here fun can either access x in dummy1 or dummy2, or any x in any function that call fun with x declared in it.

dummy1();

will print 5,

dummy2();

will print 10.

The first one is called static because it can be deduced at compile-time, and the second is called dynamic because the outer scope is dynamic and depends on the chain call of the functions.

I find static scoping easier for the eye. Most languages went this way eventually, even Lisp (can do both, right?). Dynamic scoping is like passing references of all variables to the called function.

As an example of why the compiler can not deduce the outer dynamic scope of a function, consider our last example. If we write something like this:

if(/* some condition */)
dummy1();
else
dummy2();

The call chain depends on a run time condition. If it is true, then the call chain looks like:

dummy1 --> fun()

If the condition is false:

dummy2 --> fun()

The outer scope of fun in both cases is the caller plus the caller of the caller and so on.

Just to mention that the C language does not allow nested functions nor dynamic scoping.

Lexical Scope in JavaScript

Your understanding of how scope works for standard functions (including closures inside closures) is correct, but for arrow functions this statement is wrong:

"this" is bound to obj because of the lexical scoping of "this" with arrow functions.

With an arrow function this within the function is the same as whatever this was outside the function when it was created. It is not bound to obj in your example, but instead to whatever it was already bound to where that obj is being created.

It is useful in a situation such as:

this.values.filter( x => x < this.max );

Inside that arrow function this is the same as it was outside the function. With a regular function it might have been written like this:

this.values.filter( function ( x ) { return x < this.max }.bind( this ) );

or:

var self = this;
this.values.filter( function ( x ) { return x < self.max } );

Lexical scoping in ES6 / Node

As mentioned by Benjamin Gruenbaum, let and const don't hoist at all.

As a matter of fact, there are new rules that apply to let and const, such as the…

temporal dead zone

Now, if these were var declarations, everything would be clear. But with let and const, ES6 introduces a new concept of the temporal dead zone. This includes a new, subtle dynamic.

Let's have a look at two examples:

Hoisting classically would work in an example like this:

'use strict';
var x = 10;

console.log(x);
console.log(y); // This should NOT crash

var y = 5;

But if we were to replace the var declarations with let declarations, it would crash:

'use strict';
let x = 10;

console.log(x);
console.log(y); // This crashes: ReferenceError: can't access lexical declaration `y' before initialization

let y = 5;

Why does this crash?

Because unlike var assignments, accessing variables defined using let before the actual let statement is invalid (they are in the temporal dead zone).

2. Temporal Dead Zone in this case

In this case however, the temporal dead zone is not an issue. Why?

Because while we define the function with the console.log(y) statement beforehand, the actual function call and thus variable access only happens towards the end of the code. So the variable bindings are only evaluated at this point (thanks again, @BG):

'use strict';
let x = 10;
function f() {
console.log(x);
console.log(y); // This should not yet crash
}

let y = 5;
f(); // console.log(y) is only called here

If you were to reverse the order of let y = 5; and f();, your code would crash.

What is lexical scope in reactjs

React is a JavaScript library. The example you've mentioned is of lexical scope. It follows all principles of JavaScript. You can get more on scoping in the below links:

  • https://spin.atomicobject.com/2020/04/08/react-contexts-dynamic-scope/
  • https://medium.com/the-andela-way/fundamental-javascript-concepts-to-help-you-get-started-with-react-7067763d3697


Related Topics



Leave a reply



Submit