Javascript Hoisting - How are we Accessing Certain Variables? - javascript

I have two questions about hoisting:
The way function declarations are hoisted is that they go to the very top, even above variable declarations, to my understanding.
If we have this code:
function fn() {
callback();
}
function callback() {
console.log('why does this show');
}
I don't understand how this works, since both functions are hoisted to the top (which effectively produces the same code that already exists). But callback is still created below fn, and I don't see why we can access it in fn. My guess is it has something to do with the top level objects being able to access each other regardless of lexical position.
Similarly:
var a = 10;
function fn() {
console.log(a);
}
fn();
How does this work? Because the way I understand hoisting makes it seem like the function should be hoisted even above var a, which makes it seem like variables should always be inaccessible in functions.

We can go down the rabbit hole with this but I want to try to give a brief explanation on how your examples work.
Whenever the JavaScript engine creates an execution context (also known as calling stack) whether through functions or code in the global scope it creates an lexical environment. Which is a data structure that holds a collection of name/value pairs about variables and functions in it's own scope or from it's parent scope by using a reference.
About your first example. Both functions get added to the global execution context. If you call fn() in your first example initially. It will then add callback() to the call stack of fn() and execute it accordingly. So, the order of your functions don't really matter in this case.
You're second example is a different case. The execution context knowns you are referring to the global variable and therefor adding a reference to the lexical environment and that makes it able to use the variable inside fn().
This can be quite hard to get a grasp of. There are a ton of resources related to hoisting, scopes, lexical environments and execution contexts so be sure to check those out. :)

This is because how our Javascript Engine parse and compile the code.
I'm not an expert but V8 (The Chorme Engine for JS) in the first file get all the variables and functions names and store all the function references. So, you can "use" a function before "declare" because JS know where the function is.
Some languages, even C++ you could do that and is a nice feature :)

Related

Does hoisting takes place at once for the full code or by nested-function-levels

Hy guys. I dont understand something regarding the hoisting and it can be it is my bad, but I didnt find any answer, neather here nor on google, thatswhy I ask, thanks for reading.
So I dont understand, As the javascript engine gets my code below and starts to scan through,
will be the whole code with all functions and nested functions scanned threw, until to the very last scope?
And the creation phase of all function will take place for the first scan (or with others words will the full code be scanned just once and prepared everything for each functions)?
/* Global execution context*/
function myFirst(){ /*Scanner meets this code and hoists it*/
var A = "12"
return function myFirstB(){ /*As the scanner arrived here and
scanns threw this function during the parents hoisting period ( or just before the global contexts execution phase) will it be hoisted as well, that it gets [[Scopes]] property? So that when I call it in the last line as a closure, it can remember on, that variable "A" is in its outer-environment?*/
console.log(A)
} //myFirstB()
} // myFirst()
function mySecond(){
alert("one")
}
var myClosure = myFirst();
myClosure(); /*before beeing called does this function have already [[Scopes]] property/scope-chain?*/
Or the hoisting happens nest-level by nest-level? So I mean at first those functions will be hoisted which are defined in the global context?
and then as one of those functions gets invoked and its execution-contexts execution phase starts, will be its nested functions hoisted?
I am investigating this, because I dont really udnerstand, how a nested function remembers on, in which lexical environment/function has it been defined, if it wasnt already at least hoisted, that it has a [[Scopes]] property, which preserves its scope chain
The probelm is all the articles I saw until now and even the ecmascript 6 documentation says only, that the hoisting happens, if the scanner meets a function definitiona and then the scope property will be created with the scope chain and variable object the arguments object and the "this" keyword, but I didnt find any material which would talk about, if the nested functions (which are preserved in the variable object, coupled there with a reference to their function body in the memory) will be at least hoisted as well (at the same time, their parent function is hoisted) and soo they get a scope chain to remember on their outer environment, if they are called outside from there outer-environment
Thanks a lot guys for reading threw my tonns of words, if you can answer it or if you have an article which talks about this aspect as well of hoisting, I would really appriciate
I think you are confused because you tangled too many things. You will need to distinguish three things:
what the parser does
what happens when a scope is created
what happens when code is run
The parser does indeed scan through the whole code. If there was a syntax error anywhere, none of the code would be run. It does parse the whole code into a (nested) structure that is suitable for execution later. This might be an abstract syntax tree or executable byte code, or anything in between - that's an implementation detail.
Before a chunk of code is run, like in the global scope or a block scope or a function scope, the context for that execution has to be created and initialised first. It does get a parent scope reference (e.g. the scope surrounding a block or the scope a closure was defined in), a this value, and a new variable environment in which the variables of this scope are created. Here is where all the variable names declared in the scope (e.g. function parameters, var and function and let and const and class declarations etc) are used to instantiate a new variable.
When the code chunk is executed statement for statement and expression for expression, the variables already exist. This is when the values are created and assigned to the variables. When a function is defined, it does become a closure by referencing the current scope.
The term "hoisting" is giving the wrong impression. No source code is moved around. How an implementation achieves the specified behaviour is not restricted. It might be that the parser creates byte code that has the creation of the variables at the top of each scope. It might be that in the initialisation phase of a scope it scans the AST for declarations every time. It most likely is a mix of those in the form of a just-in-time compiler, which creates the byte code only when the function is called for the first time.
Regarding your question about nested functions, remember that the inner function is re-created every time the outer function is called. It is only "hoisted" to the top of its scope, not outside of the outer function, and will be redefined on every run of the code.
Let me explain to you step by step.
Step 1 (by parser): Scans the whole code (all levels of nesting) to create an AST (abstract syntax tree) and to checks for syntax errors.
Step 2 (by JS engine): Hoists code belonging to the current level only. Then executes current level code. This code may have nested code.
Step 3 (by JS engine): Does Step 2 for nested code.
This process repeats, until all code is executed, for all levels.
PS: Some help taken from this answer.

Get the current scope of a Javascript Function [duplicate]

When I call a function, a local scope is erected for that call. Is there any way to directly reference that scope as an object? Just like window is a reference for the global scope object.
Example:
function test(foo){
var bar=1
//Now, can I access the object containing foo, bar, arguments and anything
//else within the local scope like this:
magicIdentifier.bar
}
Alternately, does anyone have a complete list of what is in the local scope on top of custom variables?
Background: I'm trying to get down to a way of completely shifting to global scope from within a function call, the with statement is a joke, call works a little better, but it still breaks for anything declared in function scope but not in global scope, therefore I would declare these few cases in global scope, but that requires me to know what they are. The IE function execScript makes a complete shift, but that only solves the problem for IE.
Note: To anyone loading JavaScript dynamically, setTimeout(code,1) is a simple effective hack to achieve global scope, but it will not execute immediately.
No, there's no way to reference the variable object of the execution context of a function binding object of the variable environment of the execution context (that's what that thing is called [now; hence the strikethrough]; details in §10.3 of the specification). You can only access the limited view to it you get with arguments (which is very limited indeed).
Usually when I've wanted to do this, I've just put everything I wanted on an object and then used that (e.g., passed it into a function). Of course, any functions created within the context have access to everything in scope where they're created, as they "close over" the context; more: Closures are not complicated.
I know this is hugely late, and you're probably not even slightly interested any more, but I was interested in the feasibility of this too and you should be able to make a work around of some sort using:
(function(global) {
var testVar = 1;
global.scope = function(s) {
return eval(s);
}
})(this);
then running:
scope('testVar'); // 1
returns the variable from within the closure. Not particularly nice, but theoretically possible to wrap that in an object, perhaps using some validation and getters and setters if you needed?
Edit: Having re-read the question, I assume you'd want to access it without having to specify a function in the scope itself, so this probably isn't applicable. I'll leave this here anyway.
Certain versions of Netscape had a magic property in the arguments object that did what you're looking for. (I can't remember what it was called)
What about something like this?
<script type="text/javascript">
var test = {
bar : 1,
foo : function () {
alert(this.bar);
}
}
test.foo();
</script>
You don't need a keyword to reference a variable in the local scope, because it's the scope you're in.

Why can deep nested function access top level vars?

I've been doing some javascript reading, and I've gathered that a closure has access only to the closure "wrapping" it, or, you might say it's immediate parent. Now I've been playing a bit, and I see in this jsfiddle that even deep nested functions have access to to vars defined way up.
Can anyone please explain that? Or explain what have I got completely wrong?
http://jsfiddle.net/tPQ4s/
function runNums() {
this.topVar = 'blah';
return function(){
(function() {
(function() {
console.log(topVar);
})();
})();
}
}
var someFunc = runNums();
someFunc();
Without going too deep into the details, a closure technically describes a array like variable within the such called Activation Object that is handled from the javascript engine. An ActivationObject contains Variables declared by var, function declarations and formal parameters.
That means, anytime a new function (-context) is invoked, internally a new Activation Object is created. That object is part of the new Execution Context, a typicall EC looks like:
this context variable
Activation Object
[[Scope]]
The interesting part here is [[Scope]]. That variable contains all Activation Objects of all parent context and is filled when the EC is called. So now, when a function wants to access a variable, the name resolution process first looks into its own Activation Object, if nothing is found the search continues in the "Scope chain", which is just an Indexed search through our [[Scope]] variable (which again, is an array of parent contexts). Thats why we also speak a lot about "lexical scope" in ECMA-/Javascript.
Note: The above behavior is not described entirely, that would need several pages of text. Also it describes the ECMAscript3 262 specification. Things work a little different in ES5, but its still around the same thing
That is because the chain runs further up to the top context.
In the example, that would be:
window < runNums < anonymous < anonymous < anonymous
Variables living in any of these will be available in the last anonymous function. In runNums, only variables living in runNums or window will be available. In the first anonymous function, only its variables and those living in runNums or window will be available, etc.
this is nothing but the Window object here.
Here runNums is a global function and runNums() is equal to window.runNums(). So this is window and this.topVar is window.topVar. Obviously it will be accessible from anywhere.
Try this and see the difference
var someFunc = new runNums();
someFunc();
The deep nested functions have not been executed. You did not return them for executing.

Does a (JS) Closure Require a Function Inside a Function

I'm having a little difficulty with the inherent concept of a closure. I get the basic idea, but here's the thing: I thought that, technically, there "is a closure" inside every Javascript function. To quote wikipedia:
In computer science, a closure (also lexical closure, function closure
or function value) is a function together with a referencing
environment for the nonlocal names (free variables) of that function.
Such a function is said to be "closed over" its free variables.
So since you can define variables inside a function, they are "closed off" to the rest of your code, and so I see that as a closure. Thus, as I understand it:
(function(){var a = 1;}())
Is a (not very useful) example of a closure. Or heck, even just this:
function(){var a = 1;}
But, I think my understanding might be wrong. Others are telling me that for something to be a closure it has to persist a state, and so since nothing persists beyond that code it's not really a closure. That suggests that you need to have:
function(foo){foo.a = 1;}(bar); // bar.a = 1
or even (to ensure un-modifiability):
function(foo){var a = 1; bar.baz = function() { return a}}(bar); // bar.baz() = 1
So, technically speaking (I know several of the examples are practically speaking pointless, but) which of the above examples are actually examples of closures. And does a closure just have to be a space (ie. inside a JS function) where variables can be stored that can't be accessed form outside, or is persistence a key part of a closure's definition?
EDIT
Just noticed the wiki definition for the "closures" tag on Stack Overflow:
A closure is a first-class function that refers to (closes over)
variables from the scope in which it was defined. If the closure still
exists after its defining scope ends, the variables it closes over
will continue to exist as well.
While the SO wiki is certainly no final authority, the first sentence does seem to correlate with my understanding of the term. The second sentence then suggests how a closure can be used, but it doesn't seem like a requirement.
EDIT #2
In case it isn't clear from the varying answers here, the wikipedia answer, and the tag answer, there does not seem to be a clear consensus on what the word "closure" even means. So while I appreciate all the answers so far, and they all make sense if you go with the author's definition of closure, what I guess I'm really looking for is ... is there any actual "authoritative" definition of the word (and then if so, how does it apply to all of the above)?
You're being led astray by a wrong assumption of where the word "closure" comes from.
In a language-theoretic context, the point of a closure is that the function can refer to variables declared outside its own definition. It is immaterial whether it has internal variables, or that the internal variables are not visible from outside. In other words it is about seeing out from the function to its definition environment, not about seeing in from outside the function.
Why the weird word, then? Look at the function in your last example:
bar.baz = function() { return a }
This function contains a mention of the variable a which is not defined in the function body itself. It is a "free" variable of the function body, sort of a "hole" in the definition. We cannot execute the function without knowing, by some extraneous means, what variable the identifier a in the body refers to. Forming a closure at run-time pairs this "open" function body with a reference to the appropriate variable, thereby closing the hole in the definition. And that's where the name comes from.
(If you want the completely technical explanation, the underlying concept is that of a "closed" term in the lambda-calculus, which means one that has no free variables. Only closed term have independent meanings. A closure is then the combination of a (usually compiled) non-closed piece of source code, together with the contextual information that lets it behave like it was a closed term, and therefore be executable).
Addendum: In the common idiom
function() {
var blah;
// some code here
}();
the point is not to get a closure (you will get one, of course, but it doesn't do anything interesting for you), but to create a local scope for the blah variable. A local scope is conceptually quite a different thing from a closure -- in fact most C-lookalikes other than Javascript will create them at every {} block, whereas they may or may not have closures at all.
None of your samples are closures technically speaking. (But forth sample can be classified as such in some circumstances, see below)
Closure is a data structure that combines reference to a function and non-empty list of call frames (or scopes) active at the moment of declaration.
Closure is created by executing some code that contains declaration of a function that uses variables from outer scopes. In this case runtime, while executing the code, has to create not just a reference to the function but closure structure - function reference and reference to its current environment - list of call frames that hold used outer variables.
For example in my TIScript call frames are replaced on stack - when you exit from a function its call frame that includes collection of variables it uses is purged from the stack. Closure creation in my case happens when: VM meets function declaration instruction and that function is marked (by compiler) as the one that uses outer variables. In this case current chain of call frames that hold used variables is moved from stack to the heap - converted to GCable data objects and reference to the function and its call chain is stored as a reference.
Your fourth case physically does not require closure to be created - no need to store call frames for later use - bar.baz contains just a number - not a reference to function.
But this:
function(foo){
var a = 1;
bar.baz = function() { return a; };
}
creates closure in bar.baz field. When you later invoke bar.baz() function code is executed and value of 'a' variable will be taken from reference to outer call frame that is stored in closure.
Hope it clears something for you.
Closures in JavaScript (and other languages) are used to control and define scope. There's no requirement that you define a function within a function for it to "qualify" as a closure. The body of a function is a Closure. One of the more common uses is to declare a local scope variable that becomes a Private or Hidden member of some other object or function you'll return, but that's not a hard-fast rule.

JavaScript: Reference a functions local scope as an object

When I call a function, a local scope is erected for that call. Is there any way to directly reference that scope as an object? Just like window is a reference for the global scope object.
Example:
function test(foo){
var bar=1
//Now, can I access the object containing foo, bar, arguments and anything
//else within the local scope like this:
magicIdentifier.bar
}
Alternately, does anyone have a complete list of what is in the local scope on top of custom variables?
Background: I'm trying to get down to a way of completely shifting to global scope from within a function call, the with statement is a joke, call works a little better, but it still breaks for anything declared in function scope but not in global scope, therefore I would declare these few cases in global scope, but that requires me to know what they are. The IE function execScript makes a complete shift, but that only solves the problem for IE.
Note: To anyone loading JavaScript dynamically, setTimeout(code,1) is a simple effective hack to achieve global scope, but it will not execute immediately.
No, there's no way to reference the variable object of the execution context of a function binding object of the variable environment of the execution context (that's what that thing is called [now; hence the strikethrough]; details in §10.3 of the specification). You can only access the limited view to it you get with arguments (which is very limited indeed).
Usually when I've wanted to do this, I've just put everything I wanted on an object and then used that (e.g., passed it into a function). Of course, any functions created within the context have access to everything in scope where they're created, as they "close over" the context; more: Closures are not complicated.
I know this is hugely late, and you're probably not even slightly interested any more, but I was interested in the feasibility of this too and you should be able to make a work around of some sort using:
(function(global) {
var testVar = 1;
global.scope = function(s) {
return eval(s);
}
})(this);
then running:
scope('testVar'); // 1
returns the variable from within the closure. Not particularly nice, but theoretically possible to wrap that in an object, perhaps using some validation and getters and setters if you needed?
Edit: Having re-read the question, I assume you'd want to access it without having to specify a function in the scope itself, so this probably isn't applicable. I'll leave this here anyway.
Certain versions of Netscape had a magic property in the arguments object that did what you're looking for. (I can't remember what it was called)
What about something like this?
<script type="text/javascript">
var test = {
bar : 1,
foo : function () {
alert(this.bar);
}
}
test.foo();
</script>
You don't need a keyword to reference a variable in the local scope, because it's the scope you're in.

Categories