Can someone please explain how identifier resolution works for Javascript taking the following scenarios :
A global function is called .
A function inside an user defined javascript object is called .
You have to learn the context and scoping in ECMA Script to understand this. And in between is it identifier or variable?
Identifiers are normally tagged to window object. Say String() it's actually window.String().
Normally when a page loads the all the variables and functions are added as properties to the window object. The window object becomes the global context(GC) in the case of browsers. So when a global function(this is just a method nothing is there like a global function) is called the variable is just looked in the global context. And thus it'll identify the variable.
But if there is a function inside which an inner function is there then identifying a global variable will be two folds first it'll check in function scope and then in global scope. If the variable is a function variable. Then the variable will always be there in the functions execution context(EC)
Related
In the website the following lines are given:
Your global variables (or functions) can overwrite window variables (or functions).
Any function, including the window object, can overwrite your global variables and functions.
I am unable to understand what this says.
Above that paragraph you can find this:
Global Variables in HTML
With JavaScript, the global scope is the complete JavaScript environment.
In HTML, the global scope is the window object. All global variables belong to the window object.
Combined with the quote in your question - it means that because the global scope is actually the window object - it's possible to override global functions/variables.
Here is an example:
console.log(window.Math.PI);
Math = {
PI: 5
}
console.log(Math.PI);
The browser puts certain "global" (i.e. accessible anywhere in any file) functions and variables on the window object. One such example is the function window.setTimeout, which executes its argument after a given delay.
You can also access these global window.* variables without the window prefix at all, i.e.
window.setTimeout === setTimeout
That means if you assign to a global variable with a conflicting name, you can 'override' the browser defaults -
window.setTimeout === setTimeout
setTimeout = 'myString'
window.setTimeout === 'myString'
That's why it's generally best practice not to create variables in the global (window) scope.
When I declare a variable within a javascript method's parenthesis, I am provided with an interesting addition to the function object. However, I cannot actually locate the resulting logic within the function object.
[].forEach(towel = function(){console.log(42)})
console.log(towel) //function forEach.towel()
Could someone please explain the logic behind this unique declaration?
NOTE: This evaluation was all done in the Chrome Dev Console. Perhaps that contributes to the specific syntax returned?
Since you are making an assignment to a variable that has not been declared as var, it leaks to global scope.
The towel is now a variable in global scope.
I am going through the book JavaScript: The Complete Reference, Third Edition By: Thomas Powell; Fritz Schneider to have a detailed understanding of the concepts.
Scoping Rules
Outside of a function or object, variables are within the global space whether explicitly defined with var or not. Within a function or object, if the var statement is used, the defined variable will be local to the construct; without the statement, it will be global.
Commonly, JavaScript developers make assumptions about scoping rules with var that aren’t quite true. For example, a var statement found within a for loop does not scope that value to the loop. In this case, it is scoped to either the function it is within or to the global space if it is outside a function or an object.
Just to see what happens consequently, I coded like this,
When I press Ctrl+Space in Eclipse IDE for it to show JavaScript proposals, why am I able to access the variable jLocal outside the function?
As per the author description:
For example, a var statement found within a for loop does not scope that value to the loop. In this case, it is scoped to either the function it is within or to the global space if it is outside a function or an object.
Because at the bottom of your code you have:
...
jLocal = jLocal + j; // defined not in any functions
...
Making it global, but not necessary defined.
It isn't the case of a local function. myFunc is global, just as the variable jLocal is (albeit the name). Because of hoisting, jLocal is assumed to be declared on top of parent scope.
Looking more carefully, there's two variable's named jLocal. One local to myFunc and an implicit one on global scope.
Want a tip?
Put "use strict"; just before var global1 = true;. An HTML 5 implementation would be able to catch and show your error.
I was looking at adding comments to JSON and found this script that strips them out before processing making the JSON valid. I am just trying to understand how it works to make the JSON.minify() function available?
It starts with
(function(global){ ...
totally which is weird to me. I found that "global is a property of a RegExp instance, not the RegExp object" on MDN but I don't understand how it is works in this script if at all.
This snippet:
(function(global){
// your code here
// referring to the variable named "global" in this scope
// will be a reference to the default javascript global object
})(this);
is a construct for assigning the global object (whatever it might be) to an argument labeled global for all code that is inside this self-executing function.
The self executing function is used to define a separate execution scope so that any functions or variables you define inside this other scope will not interfere with or be directly accessible from outside this scope (insulating your scope from other code scopes).
In a browser, the global object is the window object, but if you intended to have code that might work in other javascript environments (like no node.js on a server) where the global object might not be window, this is a way of extracting the global value from the default this value, putting it into another variable which you can then refer to anywhere inside your code block.
For code mean to only run in a browser, there really is no point to this. You can just refer to window when you need the global object.
It's just a function parameter name. It might as well be froozboggles.
This code:
(function(foo) {
// In here, what's called "bar" in the outer scope is called "foo"
})(bar);
Defines an anonymous function taking one parameter bar and immediately calls it with the value of bar as the first parameter.
Apart from what jfriend00 mentions in his fine answer, it's also a good way of making sure that you don't leak variables and functions to the outer scope: If you declare, say, var baz = 17; in the top scope in javascript, it will be a property of window. If you wrap it in a function as in the pattern you mention, you can only export properties to window explicitly -- by assigning them to global, in the case of your example. Edit: As #josh3736 says in his comment, you can also leak to window by assigning without a previous declaration, e.g. quux = 4711;.
Compare this code1:
somevar = 5;
delete window.somevar;
alert(typeof somevar) //=> undefined, so deleted
to this code:
var somevar = 5;
delete window.somevar;
alert(typeof somevar) //=> number, so NOT deleted
See it in action here
Now in the first block, somevar is deleted, in the second block it's not. The only difference is using the var keyword in the second block. Both blocks run in the global scope.
Can this be explained?
1 the code can't be tested in a chrome-console or firebug, and not in jsfiddle either. In those environments all code is evalled, and in evalled code delete works on anything that is the result of eval (see more about that). In IE < 9 delete window[anything] is not allowed anyway.
What you're seeing is an aspect of the fact that the global object (window, on browsers) is a conflation of two different things which are distinct everywhere except the global execution context.
In the first block, someVar is a normal property of the window object. Properties can be removed via delete.
In the second block, someVar is a property of the binding object of the variable context of the global execution context — which is also window. You cannot delete properties the binding object receives in its role as the binding object (even though you can delete properties it receives in other ways). That is, you cannot delete variables declared with var (and a few other things that are added the same way).
(Sorry, not my terminology; it comes from the spec, which features some very fun language indeed.)
It's only the global execution context where we have this conflation of concepts. The variable binding object for other execution contexts (function calls, for instance) is still a very real thing (and crucial to proper functioning of closures), but there's no programmatic way to directly access it. In the global execution context, though, it's the global object, which of course we can access.
It helps to understand this if we look at functions first, and then look at the global execution context. when you call a function, these things happen:
Set this to point to the object designated by the call (the value of this is usually implicitly set, but there are ways to set it explicitly).
Create an execution context for this call.
Create a variable context for that execution context.
Create a binding object for that variable context.
Add the function's name, if it has one, to the binding object as a property referring to the function.
Add the arguments property to the binding object, referring to the pseudo-array of arguments to the function.
Add any named arguments declared in the function definition as properties of the binding object, referring to their entries in the arguments.
Add the names of of any variables declared via var statements (anywhere in the function body) as properties of the binding object, initially with the value undefined.
If there are named functions declared within the function, add their names as properties of the binding object, referring to those functions.
Put the binding object at the top of the scope chain (more below).
...and then step-by-step execution of the code in the body of the function begins. Any var statements with initializers (e.g., var a = 5; rather than just var a; are treated as assignment statements (a = 5;) when the execution point reaches them.
Throughout the above, whenever a property is added "to the binding object", it's added with a flag indicating that it cannot be deleted. This is why vars (and the names of declared functions, etc.) can't be deleted.
Any unqualified reference is looked up via the scope chain. So when you refer to a in your code, the first place the interpreter looks is the binding object at the top of the scope chain. If it has a property called a, that's what gets used; if not, we look at the next link down the scope chain and use that property if we find it; and so on until we run out of links on the scope chain. The global object is the bottommost link of that chain (which is why global variables work).
So what's different about the global context? Well, very little, actually. Here's the sequence (roughly):
Create an execution context for this call.
Create a variable context for that execution context.
Create a binding object for that variable context.
Set this to point to the binding object; that makes it the global object.
Set some default properties on that object as defined by the environment (in browsers, for instance, the property window is added to the object, referring to itself).
...and then we basically pick up with step 8 in the function stuff:
Add the names of of any variables declared via var statements (anywhere in the global scope) as properties of the binding/global object, initially with the value undefined.
If there are named functions declared within the global scope, add their names as properties of the binding/global object, referring to those functions.
Put the binding/global object at the top of the scope chain (more below).
...and start step-by-step execution of the code (again with var initializers becoming assignments).