delete: can someone explain this behavior - javascript

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).

Related

Where does enclosing function reside post its execution or after returning closure function?

Having understood the basics of Closures there is one doubt that's still haunting me :
Where does enclosing function reside post its execution or after returning closure function ?
I believe functions reside in stack data structure and knocked off the top of stack once function finishes its execution / returns any value.
But in Closures, inner function will still have to access to the state of Enclosing function, how ?
function sayHello(name) {
var text = name + ' !!!'; // Local variable
return function(wish) { console.log(wish + ', ' +text); }
}
var say = sayHello('Bob');
say('Hey');
say('Hello');
Where is sayHello present once it returns a function, as its removed from function stack frame ?
This is one very good article on this.
https://dmitryfrank.com/articles/js_closures
Scope chain
When any JavaScript code is executing, it needs some place to store its local variables. Let's call this place as a scope object (some refer to it as a LexicalEnvironment). For example, when you invoke some function, and function defines local variables, these variables are saved on the scope object. You can think of it as a regular JavaScript object, with the notable difference that you can't refer to the whole object directly. You can only modify its properties, but you can't refer to the scope object itself.
This concept of scope object is very different from, say, C or C++, where local variables are stored on stack. In JavaScript, scope objects are allocated in heap instead (or at least they behave like this), so they might stay allocated even if function already returned. More on that later.
As you might expect, scope object might have parent. When the code tries to access some variable, interpreter looks for the property of current scope object. If the property doesn't exist, interpreter moves to the parent scope object, and looks there. And so on, until the value is found, or there's no more parent. Let's call this sequence of scope objects as a scope chain.
The behavior of resolving a variable on scope chain is very similar to that of prototypal inheritance, with, again, one notable difference: if you try to access some non-existing property of regular object, and prototype chain doesn't contain this property either, it's not an error: undefined is silently returned. But if you try to access non-existing property on the scope chain (i.e. access non-existing variable), then ReferenceError occurs.

Javascript: {} vs new Object() performance [duplicate]

This question already has answers here:
What is the difference between `new Object()` and object literal notation?
(12 answers)
Closed 9 years ago.
I want to understand why is the difference in performance when both does same thing?
Benchmark
Performance of {} can be explained as :
{} is the literal for object in Javascript, and literals are evaluated faster.
As an added bonus, literals take up less space in your code, so the overall file size is
smaller.
The end result of literal code is the same as the new Object() code, but it is executed faster in almost all browsers (Firefox 3.5 shows almost no difference).
As the number of object properties and array items increases, so too does the benefit of using literals.
Object Literals {} are executed faster because of scope managing mechanism in Javascript
When JavaScript code is being executed, an execution context is created. The execution context (also sometimes called the scope) defines the environment in which code is to be executed.
A global execution context is created upon page load, and additional execution contexts are created as functions are executed, ultimately creating an execution context stack where the topmost context is the active one.
Each execution context has a scope chain associated with it, which is used for identifier resolution. The scope chain contains one or more variable objects that define in-scope identifiers for the execution context.
The global execution context has only one variable object in its scope chain, and this object defines all of the global variables and functions available in JavaScript.
When a function is created (but not executed), its internal [[Scope]] property is assigned to contain the scope chain of the execution context in which it was created (internal properties cannot be accessed through JavaScript, so you cannot access this property directly).
Later, when execution flows into a function, an activation object is created and initialized with values for this, arguments, named arguments, and any variables local to the function. The activation object appears first in the execution context’s scope chain and is followed by the objects contained in the function’s [[Scope]] property.
During code execution, identifiers such as variable and function names are resolved by searching the scope chain of the execution context.
Identifier resolution begins at the front of the scope chain and proceeds toward the back. Consider the following code:
function Add(n1, n2) {
this.n1 = n1;
this.n2 = n2;
this.val = this.n1 + this.n2;
}
var result = new Add(5, 10);
When this code is executed, the add function has a [[Scope]] property that contains only the global variable object.
As execution flows into the add function, a new execution context is created, and an activation object containing this, arguments, n1, and n2 is placed into the scope chain.
Below Figure , “Relationship of execution context and scope chain” illustrates the behind-the-scenes object relationships that occur while the add function is being executed.
Inside the add function, the identifiers num1 and num2 need to be resolved when the function is executing.
This resolution is performed by inspecting each object in the scope chain until the specific identifier is found.
The search begins at the first object in the scope chain, which is the activation object containing the local variables for the function.
If the identifier isn’t found there, the next object in the scope chain is inspected for the identifier. When the identifier is found, the search stops.
In the case of this example, the identifiers num1 and num2 exist in the local activation object and so the search never goes on to the global object.
Understanding scopes and scope chain management in JavaScript is important because identifier resolution performance is directly related to the number of objects to search in the scope chain.
The farther up the scope chain an identifier exists, the longer the search goes on and the longer it takes to access that variable; if scopes aren’t managed properly, they can negatively affect the execution time of your script.

Variable/Lexical environments

As said in sec 10.4.3
The following steps are performed when control enters the execution
context for function code contained in function object F, a caller
provided thisArg, and a caller provided argumentsList:
If the function code is strict code, set the ThisBinding to thisArg.
Else if thisArg is null or undefined, set the ThisBinding to the global object.
Else if Type(thisArg) is not Object, set the ThisBinding to ToObject(thisArg).
Else set the ThisBinding to thisArg.
Let localEnv be the result of calling NewDeclarativeEnvironment passing the value of the [[Scope]] internal property of F as the
argument.
Set the LexicalEnvironment to localEnv.
Set the VariableEnvironment to localEnv.
Let code be the value of F‘s [[Code]] internal property.
Perform Declaration Binding Instantiation using the function code code and argumentsList as described in 10.5.
Consider the following code snippet:
function foo(){
var a={p:'p'};
o={c:'c'};
}
Thus we have the following:
Code of our function isnt a strict code
thisArg is null hence, ThisBinding set to the global object
---
---
I dont understand what bindings will be contains environment record represented by [[Scope]] internal property.
Set the LexicalEnvironment to environment which geted at step 5.
Set the VariableEnvironment to environment which geted at step 5.
Perform declaration binding instatiation.
At step 8 bindings are created in the VariableEnvironment, but not in LexicalEnvironment. But in sec 10.3 said that
When an execution context is created its LexicalEnvironment and
VariableEnvironment components initially have the same value.
Question:
Why just after creation of execution context LexicalEnvironment and VariableEnvironment is still equal in my case above?
I am not sure I understand your question, but this is how I understand sec 10.4.3 :
steps 1 to 4 are dealing with the value of this. Basically, in strict mode, this will be left to a null or undefined value instead of defaulting to the global object (window in case of a browser). This covers the cases when a function is not invoked through usual object or event handler mechanisms.
step 5 to 7 mean that a new naming environment is created each time you enter a function.
It describes the creation of this environment, which is linked to the previous one to form the current name scope.
For each new function, two environments are co-existing.
When a name is resolved, Lexical environment is searched first, then Variable environment. If both searches fail, the process is repeated at the upper level of the environment chain, until the 'catch-all' global scope is encountered. In this scope, all identifiers are handled as properties of the global (window) object. You can picture it as the whole code being enclosed in a with (window) block.
Lexical environment can be seen as a temporary augmentation of the variable scope.
Lexical and Variable environments are functionnally identical until you alter the lexical environment with two specific statements: with or catch. It does not mean they are implemented as identical data structures.
In terms of implementation, you could imagine the lexical environment as an empty list and the variable environment as a list containing all local variable and parameter names.
When a catch or with statement is encountered, the lexical list is populated with new names that will take precedence over the ones stored in the variable list.
catch will simply make its argument available for name resolution (i.e. allow you to reference the exception parameter). No big deal since the new name is just as explicit as a function parameter.
with is a rather more dangerous beast. It will create a new environment with the names of all properties of the object passed as its argument. The scope will consist of the chain of variable environments plus this new lexical environment.
Here the new names available for resolution are 'hidden' inside the object.
For instance:
var a = 'a', b = 'surprise!', o = {a:'a'};
with (o) { a = b; }
console.log (a+" "+b+" "+o.a);
will yield
a surprise! surprise!
a is resolved as o.a since o contains a property named a.
b is not found inside the lexical environment and thus the current variable environment is tried and variable 'b' is found.
This is a pretty dangerous mechanism, because if you believe an object contains a given property while it actually doesn't, you will instead reference a variable outside the current scope.
For instance, a simple typo like this:
with (element.style) {leftt = '10px';}
will set the window.leftt property to '10px', unless you happen to have declared a variable named leftt somewhere in the current scope.
Now if you give silly names like 'i' or 'j' to your object properties, chances are you will clobber a random loop index somewhere up the scope chain while believing you are setting the property of an object.
step 8 describes the parameters binding once the function scope is established. Basically, the parameters are bound with the values and their names are added to the variable environment.
The whole point of keeping two separate environments is that the hoisting mechanism always uses the variable environment chain as a scope.
The idea is that a variable or function should behave as if it had been declared at the top of the current scope block, so for instance a function declared inside a with block should not resolve its names with the object properties exposed by the with statement.
Frankly this is a rather moot point, since ECMA spec does not allow function declarations inside blocks, although most implementations do, with varrying results.
Now for your example:
function foo(){
var a={p:'p'};
o={c:'c'};
}
Your function does not contain any with or catch statements, so the scope chain inside 'foo()' is just a list of two variable environments :
global (a bunch of DOM objects all seen as properties of 'window')
function foo (var a)
once you call foo(),
a will resolve as foo's local variable, will be created as an object with the property p of value 'p' (and garbage collected as soon as you leave foo(), unless you manage to reference it from a persistent variable).
o will not be found in foo's variable environment, so it will be caught by the 'catch-all' global scope and thus resolved as a (new) property of the window object. It will create a window.o.c property with the value 'c'.
Does that answer somewhat to your question?

What does the global in (function(global){ some code .. })(this) do?

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;.

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.

Categories