Is jQuery / Javascript code executed line by line? [duplicate] - javascript

I understand that JavaScript is interpreted and not compiled. No problem there. However, I keep reading here that JavaScript is executed "on the fly" and that lines are read one at a time. This idea is confusing me quite a bit when it comes to the following example:
writeToConsole();
function writeToConsole() {
console.log("This line was reached.");
}
For the record, this bit of code will write to the console just fine. Still, how would the browser know of the existence of exampleFunction() if it had not yet reached the function?
In other words, when exactly is this function first interpreted?

First, you make an incorrect assumption: modern JavaScript is compiled. Engines like V8, SpiderMonkey, and Nitro compile JS source into the native machine code of the host platform.
Even in older engines, JavaScript isn't interpreted. They transform source code into bytecode, which the engine's virtual machine executes.
This is actually how things in Java and .NET languages work: When you "compile" your application, you're actually transforming source code into the platform's bytecode, Java bytecode and CIL respectively. Then at runtime, a JIT compiler compiles the bytecode into machine code.
Only very old and simplistic JS engines actually interpret the JavaScript source code, because interpretation is very slow.
So how does JS compilation work? In the first phase, the source text is transformed into an abstract syntax tree (AST), a data structure that represents your code in a format that machines can deal with. Conceptually, this is much like how HTML text is transformed into its DOM representation, which is what your code actually works with.
In order to generate an AST, the engine must deal with an input of raw bytes. This is typically done by a lexical analyzer. The lexer does not really read the file "line-by-line"; rather it reads byte-by-byte, using the rules of the language's syntax to convert the source text into tokens. The lexer then passes the stream of tokens to a parser, which is what actually builds the AST. The parser verifies that the tokens form a valid sequence.
You should now be able to see plainly why a syntax error prevents your code from working at all. If unexpected characters appear in your source text, the engine cannot generate a complete AST, and it cannot move on to the next phase.
Once an engine has an AST:
An interpreter might simply begin executing the instructions directly from the AST. This is very slow.
A JS VM implementation uses the AST to generate bytecode, then begins executing the bytecode.
A compiler uses the AST to generate machine code, which the CPU executes.
So you should now be able to see that at minimum, JS execution happens in two phases.
However, the phases of execution really have no impact on why your example works. It works because of the rules that define how JavaScript programs are to be evaluated and executed. The rules could just as easily be written in a way such that your example would not work, with no impact on how the engine itself actually interprets/compiles source code.
Specifically, JavaScript has a feature commonly known as hoisting. In order to understand hoisting, you must understand the difference between a function declaration and a function expression.
Simply, a function declaration is when you declare a new function that will be called elsewhere:
function foo() {
}
A function expression is when you use the function keyword in any place that expects an expression, such as variable assignment or in an argument:
var foo = function() { };
$.get('/something', function() { /* callback */ });
JavaScript mandates that function declarations (the first type) be assigned to variable names at the beginning of an execution context, regardless of where the declaration appears in source text (of the context). An execution context is roughly equatable to scope – in plain terms, the code inside a function, or the very top of your script if not inside a function.
This can lead to very curious behavior:
var foo = function() { console.log('bar'); };
function foo() { console.log('baz'); }
foo();
What would you expect to be logged to the console? If you simply read the code linearly, you might think baz. However, it will actually log bar, because the declaration of foo is hoisted above the expression that assigns to foo.
So to conclude:
JS source code is never "read" line-by-line.
JS source code is actually compiled (in the true sense of the word) in modern browsers.
Engines compile code in multiple passes.
The behavior is your example is a byproduct of the rules of the JavaScript language, not how it is compiled or interpreted.

All functions will be examined first by the browser before any code is executed.
However,
var foo = function(){};
This will not be examined, and thus the following will throw a TypeError: undefined is not a function
foo();
var foo = function(){};

It does take 2 passes. The first pass parses the syntax tree, a part of which is performing hoisting. That hoisting is what makes your posted code work. Hoisting moves any var or named function declarations function fn(){} (but not function expressions fn = function(){}) to the top of the function they appear in.
The second pass executes the parsed, hoisted, and in some engines compiled, source code tree.
Check out this example. It shows how a syntax error can prevent all execution of your script by throwing a wrench in the first pass, which prevents the second pass (actual code execution) from ever happening.
var validCode = function() {
alert('valid code ran!');
};
validCode();
// on purpose syntax error after valid code that could run
syntax(Error(
http://jsfiddle.net/Z86rj/
No alert() occurs here. The first pass parsing fails, and no code executes.

The script is first parsed, then interpreted, and then executed. When the first statement (writeToConsole();) is executed, the function declaration has already been interpreted.
Since all variable and function declarations are hoisted in the current scope (in your case, the global script scope), you will be able to call a function that was declared below.

JavaScript is actually interpreted line by line. BUT, before it's executed, there is a first pass made by the compiler, reading certain things in (pretty geeky, have a look at this: https://www.youtube.com/watch?v=UJPdhx5zTaw if you're really interested).
The point is, JavaScript will be first "read" by the compiler, who stores functions defined as function foo(){...} already. You can call those ones at any given time in the script, given you are calling them from the same or a subordinate scope. What modern compilers also do is preallocate objects, so as a side effect it does make sense to strongly type your variables for the matter of performance.
var foo = function(){...} will not be stored by the compiler, due to the fact that JavaScript is loosely typed and the type of a variable could change during execution time.

The javascript engine create a execution context before executing your code. The execution context is created mainly in two phases:
Creation phase
Excecution phase
Creation Phase
In the creation phase we have the Global object, this and outer environment reference.In the creation phase as the parser runs through the code and begins to setup what we have written for translation, it recognizes where we have created variables and where we have created function. Basically it setup memory space for variable and functions Hoisting.
Execution Phase
In this the code is run line by line(interpreting, converting, compiling and executing it on the computer).
consider the following example, in this we are able to call the function b even before its declaration. This is because the javascript engine already knows the existence of the function b. And this is also referred to as hoisting in javascript.
b();
function b() {
console.log("I have been hoisted");
}

Related

Does automatically hoisting slow down the performance of JavaScript?

Lately, I was studying Scope in Javascript. I want to know whether automatically hoisting is done at compile time or at the time of executing the code(run time). If it does at run time then I have another question does auto-hoisting will slow down the performance of the Javascript program.
something = a();
function a(){
console.log("hoisting");
return 10;
}
var something;
Should we use manual hoisting or it would be better to use automatically hoisting?
To put my comments as an answer:
People have a different understanding of what hoisting supposed to mean. Fact is that, according to the spec, every time a function is called a new execution context is created, which holds a new environment. Then the function body is processed to find all variable declarations (var, let, const (and function declarations)) and bindings for those names are created in the new environment. var declarations are initialized with undefined. Then the body is actually evaluated.
Considering this, from the perspective of the engine it doesn't really matter where you place the var declaration, the whole body has to be processed anyway.
Having said that, I would be surprised if actual implementations didn't cache that information. After all, the variable declarations in a function don't change between function calls.
As I know, There are no performance issues. The initializations are getting done in compile time. So doesn't matter you initialize on top or bottom, The JS engine will create the references in compile time.
BUT
If you forgot to initialize at the bottom, It will be initialized as undefined by default. Because of hoisting it’s considered a practice to declare functions or variables at the top of their respective scopes.
JavaScript: What is Hoisting? (Recommended)
It is not done at run time.
It's in the compile process.
So it doesn't slow down the performance.
Just before the code is executed the compiler scans for all variable and function declarations and allocates them in the memory.

When does V8 starts compiling and executing the code in relation to the event loop stack?

I have been curious of how js code is executed from beginning to the end.
I have read about the event loop and seen this great video,
how stack frames look like here,and also read about how the V8 engine compiles js code here.
Question :
When does V8 starts compiling and executing the code in relation to the event loop stack ?
is it when the function is about to get popped out of the stack?
or do all functions get compiled, right before they are placed on the stack ?
therefore the proccess of putting other function on top is acctually only dealing with machine code, if so does the execution of that machine code occurs when popping the function from the stack ?
In case my question is not understood, i believe via this example it would be better understood
Example :
function foo() {
var name=`foo`;
var obj = {
number: 6
}
console.log(obj.number);
}
function baz() {
var name = `baz`;
console.log(a);
foo();
}
baz();
the first process that occurs is lazy parsing, where all the file is being parsed for syntax errors, but not fully parsed so it takes less time.
going through the function declerations
does the v8 engine now compiles the function declaration code to
machine code ? or its not his turn yet..
baz is called , baz is placed on bottom of the stack ,and in its stack frame the name variable value is stored (since its a primitive).
when exactly does buz gets parsed and converted to machine code ? before its placed on the stack ? or when it pops off ?
console.log placed on top of baz and is executed, - console shows baz
is this is the
place where the console.log js code is compiled to machine code and executed ?
console.logs pops of the stack.
foo is placed on top of baz, obj is placed in heap (since its a reference type), and name=foo is placed in foo`s stack frame.
console.log goes on top of foo, and is executed , console shows 6.
console.log pops off.
foo pops off, along with its local variable value.
baz pops off along with its name=baz local variable
There is no such thing as "the event loop stack".
One concept is the "call stack", which is a term for the fact that when functions call each other, they form a stack-like current state of things. This is mostly a theoretical concept, but as it happens, there is indeed an area of memory that is called "the stack" and is used for functions' local variables, but it is not a data structure with a push/pop interface: the act of calling a function places its data on this stack, and returning from the function removes it again, returning control to the calling function.
This answers part of your function: starting to execute a function is literally exactly the same as having this function placed on the call stack. Those are two descriptions for the same thing.
Another concept is the event queue. You can think of it as a queue of functions waiting to be executed; whenever no other function is executing, the next function from this queue is called. Putting a function into the queue does not require it to have been parsed or compiled. In your example snippet, the event queue is not used at all.
Compiling functions is really unrelated to all this. When a function is called (by another function, or by the event loop), it has to be executable in some form -- but depending on your JavaScript engine, it could get interpreted without any compilation, or it could get compiled to bytecode, or it could get compiled to machine code, or the engine could use this opportunity to switch from one to the other.
Since you asked about V8 specifically: in current versions, when V8 sees a function definition like function f() { ... }, it doesn't do anything anything yet (except for a few cases where V8 guesses that the function will be executed soon, in which case it creates bytecode for it immediately). If the function gets queued as a callback, still no parsing or compilation happens. When a function is called for the first time, V8 creates bytecode for it. When the function is called again, the bytecode exists already, so no additional work is required. When a function runs hot enough, V8 eventually decides to compile optimized machine code for it, usually on a background thread. Additional calls to it are opportunities for V8 to check whether the background thread is done producing machine code already; if so, then the next call will use that optimized code instead of interpreting the function's bytecode like the earlier calls did. Note that these implementation details can and will change over time.
One more note for clarification:
in its stack frame the name variable value is stored (since its a primitive).
Not quite. The variable itself is stored in the stack frame, but only as a reference. Whether it refers to a primitive value or not doesn't matter; strings and objects are both allocated on the heap. The local variable will be destroyed when the function returns and its stack frame is torn down; the respective object or string on the heap will (eventually, at some indeterminate time) be cleaned up by the garbage collector.

Execute arbitrary javascript in a custom global context

My only requirement for executing this arbitrary js code is that certain global variables/functions (e.g. setInterval) are not exposed.
My current strategy involves parsing through the js code and making a var declaration (at the beginning of the enclosing closure) for every global reference.
I'm wondering if there's any other obvious way to solving this.
Also just to clarify, this arbitrary code is not being run with things like eval. Rather, it's being wrapped inside a closure and appended to the base code.
One of the options is to override the globals by supplying your own function or variables. Example:
window.alert = function() {
// your code goes here
// Optionally call window.alert if needed
}
This should be manageable if you have a small finite list of things you wish to hide. This will make them globally unavailable.

Javascript Eval and Function constructor usage

I'm currently experimenting on self replicating code. Out of love for the language I'd like to write it in javascript.
I'm working on a program that writes a function's code which in turn writes its function own code and so on. Basically, the desired process is this:
I manually create A function which returns code (which includes some randomness) and a numeric value (proposed solution to a problem).
I call this function a number of times, evaluate the results of each of those returned functions, and continue the process until I have code that is sufficiently good for what I'm trying to do.
Now, I have always been told how eval is evil, how never to use it and so on. However for my specific use case it seems like the Function constructor or eval are exactly what I'm looking for.
So, in short the question is:
Are eval/Function constructor indeed the best tools to use in my case? If so, I figured I'd use the Function constructor to scope the code executed, but is there a way to truly limit it from accessing the global scope? Also, what are some good practices for eval usage in my case?
I think I just figured out something I could use:
If I run my javascript code using node.js I can use the vm module which allows me to execute javascript code safely in a new context, and without letting the executed code have any access to the local or global scopes.
vm.runInNewContext compiles code, then runs it in sandbox and returns the result.
Running code does not have access to local scope. The object sandbox will be used as
the global object for code. sandbox and filename are optional, filename is only used in
stack traces.
You can see a full example here: vm.runInNewContext
This will allow me to eval code safely, and seems to be the safest way (I found) currently available. I think this is a much better solution than eval or calling the Function constructor.
Thank you everyone who helped.
Unfortunately I believe there is no way to prevent it from accessing the global scope. Suppose for example that in a web browser i evaled some code like this :
(function(window) {
eval(script);
)(null));
Any time the script tries to access window - it will get an error, since window is null. However someone who knew what they were doing could always do this :
var global = (function() {
return this;
}());
Since when you invoke a function in what Crockford calls the "function invocation style" then the this is always bound to the global variable.

Does javascript still allocate memory for the "IF" scenario if the condition evaluates to false?

Soooooooooooooooo...
I have an IF statement that nowadays will evaluate to true 99.7% of the time, which consists of a check to see if the browser is DOM 1+ capable, and then load a big block of code.
So it's logical to put an "if (true)", and omit the "else" part, but i wonder if the older browsers will still continue to parse the code and allocate memory, before finally deciding to break execution....
Not that i care at this point, since we've had decent browsers for 10+ years now, but for future reference, i hope somebody knows.
I guess my question is more or less this: does the browser parse the whole file and allocate memory before executing the first conditional statement, which is the first thing before anything else?
Thanks in advance :)
There are two things that are hoisted out of execution context and will have an effect even if the code in question is never reached: function and var.
Putting a var declaration in a code block will “reserve memory” for that variable as soon as the block is entered, but the value of that variable will only be a pointer to the undefined object, so it's only a trivially small number of bytes.
Putting a function statement in a code block will both “reserve memory” for the variable and evaluate the function, assigning the resulting Function object to the variable, before the first line of code in the block is executed. That's how you can call a function that's only defined further down the script.
Under ECMAScript standard rules, you may only put function statements in the root of the code block; that is to say this:
if (true) {
function f() {
...
}
}
is illegal. However, browsers still generally allow it and exactly what happens when you do it differs between browsers. Avoid this. (Also avoid named inline function expressions, which are erroneously subject to hoisting and double-evaluation in IE's JScript.)
If you really want to stop any memory being allocated for variables and functions you don't intend to use, put them in a function block of their own. This is a common tactic anyway for maintaining clean namespaces in library code. eg.:
if (condition) (function() {
var foo= 1;
function bar() {
alert(foo);
}
})();
The amount of memory you'll save by doing this is pretty minuscule.
But every major browser today is DOM Level 1 capable; if you have backup code in your scripts to support Netscape 4, it is long past time to delete that. The baseline desktop browser right now is IE6.
The only browser in use today for which simple DOM manipulations are still a problem is IEMobile, versions prior to IEMobile 8/WinMobile 6.1.4. However this browser is so bad almost no scripts will work as-is; workarounds are required for pretty much everything.
Yes, the browser will parse the whole file. As for the "memory allocating" part. If you mean "allocate memory for all variables defined in the file" then no, it will only allocate it when the execution flow comes to that variables.

Categories