How can I implement the following JavaScript closure in strict mode? - javascript

The following code
'use strict';
function blah() {
if (1 ==21) {
}
else {
var i = 10;
function inner() {
console.log(i);
}
}
}
Produces the following error:
SyntaxError: In strict mode code, functions can only be declared at
top level or immediately within another function.
How can I write my function inner such that it has access to my variable 'i'? According to strict mode I need to move the function to the top but at this point 'i' has not been declared

Since var i will be hoisted to the top of function blah's scope anyway, you could do this:
'use strict';
function blah() {
var i;
function inner() {
console.log(i);
}
if (1 ==21) {
}
else {
i = 10;
}
}​

Where does inner() need to be accessible from? Will this work for your purposes?:
var inner = function () { ... };

It has been declared, since the var declares the variable for the entire function, not for the block.

The inner function must be declared as a function expression, like so:
var inner = function () {
console.log(i);
};

Related

Gain Access To variables defined within functions

Within Js Functions, a variable can be defined but from console that variable doesn't exist is there anyway to access or edit it?
Example:(This code would be in the website)
function whatever () {
var x = 10
}
then in console if you type
x
it will say 'undefined'
x is limited to the scope of its function. If you want to reference it outside of the function, you can either declare it outside the function:
var x = 10
function whatever () {
// ...
}
Or you can make it a global variable by declaring it with the window object:
function whatever () {
window.x = 10
}
whatever()
console.log(x)
What you're talking about is called scope. From Mozilla's docs:
function exampleFunction() {
var x = "declared inside function"; // x can only be used in exampleFunction
console.log("Inside function");
console.log(x);
}
console.log(x); // Causes error
However:
var x = "declared outside function";
exampleFunction();
function exampleFunction() {
console.log("Inside function");
console.log(x);
x = "something else";
}
console.log("Outside function");
console.log(x);
In other words, declaring variables outside the function allow access, and you can change them from within.
Alternatively, building on their example, you can use a return value in the function to assign a variable its value.
function exampleFunction() {
return "Inside function";
}
const x = exampleFunction();
console.log(x);

Why does redeclaring a function identifier within a try block throw a SyntaxError?

The following lines of JavaScript
try {
function _free() {}
var _free = 1;
} finally { }
result in the following error:
Uncaught SyntaxError: Identifier '_free' has already been declared
However, the following two blocks of JavaScript code don't:
Without the try block scope:
function _free() {}
var _free = 1;
Within a function scope:
function a() {
function _free() {}
var _free = 1;
}
But why?
(Testing environment: Chromium 61.0.3126.0)
Because block-scoped function declarations are a new ES6 feature and were made safe (i.e. throw an error on name collisions, similar to let and const), but the other cases (which are programmer mistakes regardless) needed to stay backwards compatible and silently overwrite the function.
To expand on Bergis answer, there is a difference in how the code is interpreted in ES5 and ES6 since block-scoped function declarations were added.
Input:
function test() {
try {
function _free() { }
var _free = 1;
} finally { }
}
Since ES5 does not support block-level functions, _free is hoisted to the parent function:
function test() {
var _free = function _free() { }
try {
var _free = 1;
} finally { }
}
In ES6, the function is declared at block-level, and semantically equal to a let/const declaration:
function test() {
try {
let _free = function _free() { }
var _free = 1;
} finally { }
}
This throws an error because var _free tries to declare a variable which is already declared.
For example, this throws in ES6 as well:
let _free;
var _free = 1; // SyntaxError: Indentifier '_free' has already been declared
While this is fine:
var _free;
var _free = 1; // No SyntaxError
Setting the value of the already declared identifier is fine:
let _free;
_free = 1;
Therefore, to set the declared identifier _free to 1, you need to skip the second declaration:
try {
function _free() { }
_free = 1;
} finally { }

JavaScript variable scope inside forEach loop

In the code below there is callback function used with forEach loop going over returned results. Is variable 'error' inside forEach loop and 'error' in callback same variables ?
session.getAll(options, function (error, varbinds) {
varbinds.forEach(function (vb) {
if (error)
console.log('getALL Fail ');
else
console.log(vb.value);
});
});
Yes, it is the same variable.
I'm not sure how much you know. So, I'm going to explain in detail. Scoping in JavaScript is at the function level*. Think of function definitions as points on a tree. Each point on the tree is a scope. When using a variable, you can only use what is at your current scope and anything available to ancestors going up to the top (global scope). Here are a few rules & examples that may help you better understand:
*UPDATE: ES6 const and let are block-level
Inner functions have access to outer function-level variables
function a() {
var a = 4;
function b() {
alert(a); /* a = 4 */
}
}
Parameters are defined at the same scope as if they were defined one line below
function a(a) {
// variable "a" is at same scope as the example above
function b() {
alert(a);
}
}
Variables in adjacent functions are not accessible
Function a() is the parent. b() and c() are its children. Those children cannot access each other's variables.
function a() {
function b() {
var aValue = 2;
}
function c() {
alert(aValue); /* "aValue" is undefined here */
}
}
Location of function definition is what counts
This returns 5 if you run main();:
function getValue(returnFunc) {
var a = 7;
alert(returnFunc());
}
function main() {
var a = 5;
getValue(function() { return a; }); // anonymous function becomes "returnFunc"
}
Lastly, variable overriding
(function getValue() {
var a = 5;
(function () {
var a = 7;
alert(a);
})();
alert(a);
})();
I tried to avoid using self-invoking functions/IIFEs for these examples but I just couldn't help myself on this last one. It's the easiest way, I think. Run this and you'll get 7, then 5. But, if you exclude "var" on that inner "a"...
(function getValue() {
var a = 5;
(function () {
a = 7;
alert(a);
})();
alert(a);
})();
You'll get 7, 7. This is because "var" creates a new space in memory. Also, if there is a name conflict with something in a higher scope, it gets overridden as a different variable (despite having the same name).
For some more examples, please see: What is the scope of variables in JavaScript?
Yes, it's the same variable, it would change if you define another error variable inside the scope of the forEach callback by using the var keyword:
session.getAll(options, function (error, varbinds) {
varbinds.forEach(function (vb) {
if (error) //Same error as the error parameter above
console.log('getALL Fail ');
else
console.log(vb.value);
});
});
session.getAll(options, function (error, varbinds) {
varbinds.forEach(function (vb) {
var error = false; //New error for this closure.
if (error)
console.log('getALL Fail ');
else
console.log(vb.value);
});
});

Why `var a= function(){}` is similar to `function a(){}` in the following case?

I don't understand a part of the accpeted answer of this OP:
Javascript function scoping and hoisting
Writer says:
"
Also, in this instance,
function a() {}
behaved the same as
var a = function () {};
".
What I know is that function expression is different than function declaration, at least for hoisting. Why are they similar in this case?
Why are they similar in this case?
Because var is hoisted (but not set), like a function declaration is hoisted, meaning that there is an a in the local scope before a = 10; is evaluated, so the global a never gets modified - the identifier lookup finds the local a first so sets that
Related parts of the other question
var a = 1;
function b() {
a = 10;
return;
function a() {}
}
b();
alert(a);
Why is a === 1?
That the answer was trying to say was that b is equal to
function b() {
function a() {}
a = 10;
return;
}
Similar to
function b() {
var a = function () {};
a = 10;
return;
}
i.e. there is an identifier a defined in b, so
function b() {
var a = 10;
return;
}
And now, obviously, the global a will not be modified by b
Please note that the position of the var isn't really important, just that it's there, the following will produce the same behaviour
function b() {
a = 10;
return;
var a;
}
The difference is that the first line is defined at run-time, whereas second line is defined at parse-time for a script block.
Look at the full answer on stack, here : var functionName = function() {} vs function functionName() {}

nodejs express: store parameters in variable

I am still new with nodejs, still not sure how to access a variable in a function and call the variable back.
check few links: but im getting really confused. Please help!
Node.JS: How to pass variables to asynchronous callbacks?
How can we access variable from callback function in node.js?
var express = require('express');
var app = express();
var router = express.Router();
var https = require('https').createServer( ssl_options, app);
var io = require('socket.io')( https );
**var user_id;
var room_id;**
router.use(function(req, res, next) {
next();
});
app.use('/chat',router);
router.route( '/chat/:user_id/:room_id' )
.get(function(req,res){
res.sendFile( __dirname + '/index.html' );
user_id = req.param('user_id');
room_id = req.param('room_id');
});
https.listen(3000);
io.on('connection', function(socket){
**console.log ( user_id );
console.log ( room_id );**
});
not sure how to access a variable in a function and call the variable back.
Here are some rules:
1. Variables declared inside a function are *local* to the function.
Here is an example of what local to the function means:
function do_stuff() {
var x = 10;
}
do_stuff();
console.log(x);
x does not exist until the function executes.
When the function finishes executing, x is destroyed and ceases to exist.
As a result, the line console.log(x); produces the error:
ReferenceError: x is not defined
The person who asked the question at your second link failed to understand that local variables are destroyed once a function finishes executing, so the username variable in their code cannot be accessed anywhere outside the anonymous function wherein the username variable was declared.
On the other hand, if you don't declare a variable with var, then javascript creates a global variable:
function do_stuff() {
x = 10;
}
do_stuff();
console.log(x); //=>10
That is equivalent to writing:
var x;
function do_stuff() {
x = 10;
}
do_stuff();
console.log(x); //=>10
It's generally considered bad practice for a function to manipulate the value of a variable outside the function. You should prefer the following:
function do_stuff() {
return 10;
}
var x = do_stuff();
In your case, express is the one that is going to be calling your anonymous function, and express just discards any return values. Presumably, express does something like this:
function express_get(func) {
console.log("express_get is executing");
requ = {greeting: 'hello'};
resp = {};
func(requ, resp); //Anything returned by func is not captured in a variable
}
//Here is an attempt to call express_get() and return
//the data rather than setting a global variable:
express_get(function(requ, resp) {
console.log("my callback is executing");
console.log(requ);
return {user_id: 1, room_id: 'A'};
});
--output:--
express_get is executing
my callback is executing
{ greeting: 'hello' }
Because express is calling your request handler function, and because express just discards any return value, there is no way to access the value you returned from the request handler function.
Maybe you are thinking about the problem the wrong way around? Instead of trying to figure out how to get the request data into the io.on('connect') code you should be thinking about how to get the io.on('connect') code inside the route handler function. What happens if you do this:
router.route(...).get(function(req,res){
user_id = req.param('user_id');
room_id = req.param('room_id');
io.on('connection', function(socket){
console.log ( user_id );
console.log ( room_id );
});
});
Based on all the rules discussed in this answer, you should try to determine:
Can the code inside the anonymous function passed to get() see the io variable?
Can the code inside the anonymous function passed to io.on() see the user_id and room_id variables?
2. A function's parameter variables are local to the function, too.
Here is an example:
function do_stuff(x) {
console.log(x); //=>hello
}
do_stuff("hello");
console.log(x); //=>ReferenceError: x is not defined
So x does not exist until the function executes, and x ceases to exist when the function finishes executing.
3. Variables declared inside a for loop are NOT local to the for loop.
Here is an example:
function do_stuff() {
for (var x=0; x < 10; ++x) {
console.log(x);
}
console.log(x) //=>10
}
do_stuff();
You can equivalently (and more clearly) write the function above like this:
function do_stuff() {
var x;
for (x=0; x < 10; ++x) {
console.log(x);
}
console.log(x) //=> 10
}
do_stuff();
4. Code inside a function can see the variables that existed in the surrounding scope outside the function at the time the function was *defined*.
Here is an example:
var x = 10;
function do_stuff() {
console.log(x);
}
do_stuff(); //=>10
Pretty simple. The surrounding scope means this:
//First line of program
^
|
| part of do_stuff() surrounding scope
|
v
------------------------+
function do_stuff() { |
//Do stuff |
} |
------------------------+
^
| part of do_stuff() surrounding scope
|
v
---------------------------+
function other_func() { |
|
|
//Do other stuff |
|
} |
---------------------------+
^
| part of do_stuff surrounding scope
|
v
//Last line of program
Note that the region of code inside other_func is not part of do_stuff's surrounding scope, so code inside do_stuff cannot see variables declared inside other_func.
With nested functions, the surrounding scope looks like this:
^ part of inner's surrounding scope
|
|
function outer() {
^
| part of inner's surrounding scope
|
v
----------------------+
function inner() { |
|
} |
----------------------+
^
| part of inner's surrounding scope
v
--------------------------+
function other_inner { |
|
} |
--------------------------+
^
| part of inner's surrounding scope
|
V
}
|
|
V
part of inner's surrounding scope
Here is an example of that:
var x = 10;
function outer() {
function inner() {
console.log(x);
}
inner();
}
outer(); //=>10
And for an anonymous function defined as a function argument, e.g.:
some_func(10, 20, function(req, resp) {.....});
that is almost identical to writing this:
function request_handler(req, resp) {
//Do stuff
}
some_func(10, 20, requestHandler);
And you can figure out the surrounding scope of the request_handler function using one of the diagrams above.
In computer science jargon, javascript functions are known as closures, and javascript functions are said to close over the variables in the surrounding scope that existed at the time the function was defined. If you are reading something that states some function is a closure, you can whisper to yourself, "When the function executes, it can see the variables in the surrounding scope that existed at the time the function was defined."
Here is a more complex example:
function outer() {
var x = 10;
function inner() {
console.log(x);
}
return inner;
}
func = outer();
//outer() has finished executing here.
func();
From rule 1, you might expect that after outer() finishes executing x will be destroyed, and therefore when inner() executes via func(), you will get a not defined error. However, that is not the case. inner() can still see x even though normally x would have been destroyed when outer() finished executing. inner() is said to close over the variables that existed in the surrounding scope when inner was defined.
Here is another example:
function outer() {
var x = 10;
function inner() {
console.log(x);
}
return inner;
}
func = outer();
//outer() has finished executing here.
var x = 20; //New code
func();
What will be the output there? 20? Nope. The inner() function sees the variables in the surrounding scope at the time inner() was defined--not the variables in the surrounding scope at the time inner executes.
One last example:
function outer() {
var funcs = [];
for(var x=0; x < 10; ++x) {
function inner() {
console.log(x);
}
funcs.push(inner);
}
return funcs;
}
ten_funcs = outer();
for(var y=0; y < 10; ++y) {
ten_funcs[y]();
}
What do you think the output will be? It turns out that every one of the ten_funcs outputs 10. That demonstrates that functions close over variables--not values. We know that we can rewrite outer like this:
function outer() {
var funcs = [];
var x;
for(x=0; x < 10; ++x) {
function inner() {
console.log(x);
}
funcs.push(inner);
}
return funcs;
}
So each of the ten_funcs sees the same x variable. After the functions are defined, the x variable that they can see in the surrounding scope is assigned a new value, then when each of the ten_funcs executes, it can see the variable x, and the last value assigned to x was 10. The person who asked the question at your first link was confused about this aspect of variable scoping and which variables the code inside a function can see.
The only other thing that needs to be explained is 'hiding':
var x = 20;
function do_stuff() {
var x = 10;
console.log(x);
}
do_stuff(); //=>10
This is an exception to rule 4. Inside a function, if you declare a variable with the same name as a variable in the function's surrounding scope, javascript creates a new local variable that hides the variable in the surrounding scope.

Categories