I am having a problem with an assignment. This is the assignment:
Given following function.
let rechne = function(x,y,operation) {
let ergebnis = x - y;
if (!operation) {
let ergebnis = x + y;
console.log(ergebnis);
}
return ergebnis;
}
Rewrite the function so that the desired block scope of the variables
can be achieved in ES5.
So I wrote this:
let rechneScope = function(x,y,operation) {
(function(){
let ergebnis = x - y;
})()
if (!operation) {
(function(){
let ergebnis = x + y;
console.log(ergebnis);
})()
}
return ergebnis;
}
Presumed I called that function in a console.log like console.log(rechneScope(10, 2))
I would expect the first variable to be 8 and the second one to be 12.
But when I reload the browser, the console always prints 12 for the second variable and for the first variable the result differs. Sometimes 2, sometimes 8, sometimes 15. I am really confused. Why is this happening?
First, you're assumption that the desired output is 8 then 12 is wrong. The first console.log that gets executed is the one with ergebnis = x + y, so you should see 12 then 8.
Next, let was introduced in ES6 so if you're limiting yourself to ES5, you're only allowed to use var.
Finally, make sure your you wrap the entire scope of each variable in an IIFE. You have return ergebnis outside of the first function so that variable won't be in scope anymore at the time that line of code executes.
The correct implementation would be something like this:
var rechneScope = function(x, y, operation) {
return (function() {
var ergebnis = x - y;
if (!operation) {
(function() {
var ergebnis = x + y;
console.log(ergebnis);
})()
}
return ergebnis;
})()
}
console.log(rechneScope(10, 2))
I know it's not part of your assignment, but just for reference, Babel doesn't bother with trying to emulate ES6 scope. Here's how the same thing would be compiled by Babel:
"use strict";
var rechne = function rechne(x, y, operation) {
var ergebnis = x - y;
if (!operation) {
var _ergebnis = x + y;
console.log(_ergebnis);
}
return ergebnis;
};
You are making minor mistakes.
You are using the let keyword which cares about the scope and
because of that your 'ergebnis' is undefined in return.
You are not printing the output in first block.
Solution is to remove return statement and print the answer in each block. You will get the desired result
let rechneScope = function(x,y,operation) {
(function(){
let ergebnis = x - y;
console.log(ergebnis);
})()
if (!operation) {
(function(){
let ergebnis = x + y;
console.log(ergebnis);
})()
}
}
rechneScope(10, 2);
Related
The js code has 3 functions. I want to call values from the 2 functions and execute them in the 3rd function.
function first() {
var x = 2
var y = 3
var z = x * y
}
first()
function second() {
first();
var z;
var a = z - 1
}
second()
function third() {
first();
second();
var a
var z
var ans = a * z
console.log(ans);
document.getElementById("ans_html").innerHTML = precision(ans);
}
third()
<div id="ans_html"></div>
The expected outcome was 30.
But the output was "NaN".
In most languages, including JS, variables have "scope" (mdn). If you want to share data between function's, you can either
1) return values (mdn),
function first() {
var x = 2
var y = 3
return x * y;
}
function second() {
let z = first();
return z - 1
}
function third() {
let z = first();
let a = second();
var ans = a * z
console.log(ans);
}
third();
2), less conventionally, modify a param obj since they're are passed by ref.
let func = param => {
param.x = 3;
param.y = 4;
};
let a = {};
func(a);
console.log(a);
You will need to either create global variables which is considered a bad practice, or pass values around as parameters.
Global variables:
var a
var x
var y
var z
function first() {
x = 2
y = 3
z = x * y
}
function second() {
a = z - 1
}
function third() {
first()
second()
let ans = a * z
console.log(ans);
}
Passing Parameters:
function first(x, y) {
return x * y
}
function second(z) {
return z - 1
}
function third() {
let x = 2
let y = 3
let z = first(x, y)
let a = second(z)
let ans = a * z
console.log(ans);
}
Judging based on your code, you likely should take a look into how JavaScript scopes variables based on using the keyword var vs let. I hope this helps!
You have two major issues:
Your variables a and z are not global variables. They are defined within the function itself so you cannot access those variables outside of that scope (see this)
I would not fix your code to adhere to the first issue. You don't need global variables here, you just need to return the result so you can call your functions later. In the long run, I would assume you want to add arguments to your functions, but the below is an example of how to do what you're trying to accomplish by simply returning the result in your functions.
NOTE I don't know if you have a custom precision function or what. So, I added an empty function that just returns the input. You can probably remove this.
function precision(num) {
// Insert whatever is in your precision function here...
return num;
}
function first() {
var x = 2
var y = 3
var z = x * y
return z;
}
function second() {
var z = first();
var a = z - 1
return a;
}
function third() {
var a = second();
var z = first();
var ans = a * z
console.log(ans);
document.getElementById("ans_html").innerHTML = precision(ans);
}
third()
<div id="ans_html"></div>
This is not the best design pattern, but if you want to achieve this in this way, the code is going to look like the one below. You need to return the result of the function in order to get it in another function and use it.
function first() {
var x = 2
var y = 3
return x * y
}
function second() {
var z = first()
return z - 1
}
function third() {
var a = first()
var z = second()
var ans = a * z
console.log(ans);
// document.getElementById("ans_html").innerHTML = precision(ans);
}
third()
<div id="ans_html"></div>
This question already has answers here:
Surprised that global variable has undefined value in JavaScript
(6 answers)
Closed 7 years ago.
Hi I have a snippet of code. I am confused about change of value x1 when I remove non-related part of same code. I searched about it and I came to know that it has to do with hoisting. But the value x1 is still unclear even with hoisting concept for me. Can someone please make me clear on this?
var x = 10;
function main() {
document.write("<br>x1 is " + x);
x = 20;
if (x > 0) {
var x = 30;
document.write("<br>x2 is " + x);
}
var x = 40;
var f = function(x) {
document.write("<br>x3 is " + x);
}
f(50);
}
main();
The output of this code is:
x1 is undefined
x2 is 30
x3 is 50
If I change this code to:
var x = 10;
function main() {
document.write("<br>x1 is " + x);
}
main();
The output is:
x1 is 10
So what is happening here is a common pitfall.
The simplest way to put this is. When you set var x = 30 inside your main function, you are actually redefining the scope that var x = 10 had for use inside this function. This has to do with how Javascript executes and scope.
By defining x inside the function, your scope for x has changed. Below is an example of what I mean and a version of your code that works
Example:
var test = 'test';
function run(){
console.log(test);
var test=1;
}
Your Code Updated:
var x = 10;
function main() {
console.log("<br>x1 is " + x);
x = 20;
if (x > 0) {
x = 30;
console.log("<br>x2 is " + x);
}
x = 40;
var f = function(x) { console.log("<br>x3 is " + x); }
f(50);
}
main();
Good question btw.
Since this is somewhat of a very interesting scope of how Javascript executes, consider the following code and its outputs to get the full idea
var test = 'test';
function run(){
console.log(test);
test=1;
console.log(test);
var test=2;
console.log(test);
}
console.log(test);
run();
console.log(test);
Very interesting to see how this reacts.
All variable and function declarations get "hoisted" or moved to the top of their scope. The undefined value for x is caused because the var x statement gets moved up to the top of main however the assignment = 30 does not.
So, your code will read more like this:
var x = 10; // x is 10
function main() {
var x; // x declaration is "hoisted"
document.write("<br>x1 is" + x); // x1 is undefined
x = 20; // x is 20
if (x > 0) {
x = 30; // x is 30
document.write("<br>x2 is" + x);// x2 is 30
}
x = 40; // x is 40
var f = function(x) { // x is 50
document.write("<br>x3 is" + x);// x3 is 50
}
f(50);
}
main();
You can read more about Hoisting here: JavaScript Scoping and Hoisting
In JavaScript why i value is printed when we are printing outside the scope
test();
function test(){
for(var i=0;i<10 ;i++){
console.log(i)
}
console.log('outside'+i)
}
As comparison to Java it is giving compile error?
for(int x = 10; x < 20; x = x+1) {
System.out.println("value of x : " + x );
}
System.out.print("value o " + x );
JavaScript has function scope not block scope (C, C#, C++, Java and many other programming languages have block scope). In JavaScript a variable defined anywhere inside the function will be visible anywhere in the function:
function test() {
console.log(x); // logs undefined, because x is a variable that has no value yet
if (true) {
x = 42;
} else {
var x = 5; // x is not set to 5, but it is acknowledged as a variable
}
console.log(x); // logs 42 because the value in variable x has been set to 42
console.log(y); // Error because y is not declared
}
One thing you might see mentioned regarding this is var hoisting. This means the JS interpreter will act as if all the var statements in a scope (function or global) are moved at the begining of that scope:
function foo() {
console.log(x,y);
var x = 4;
var y = 2;
var x = 0;
}
// is equivalent to:
function foo() {
var x,y;
console.log(x,y);
x = 4;
y = 2;
x = 0;
}
More details on MDN
Also, note the difference between var and let from ECMAScript6
The scope of i in this case isn't the for loop, but the test() function.
In the following example, JavaScript seems to be completely ignoring my return statement, and just carrying on executing code.
var x = 1;
(function() {
x = 2;
return;
var x = 3;
})();
console.log(x); // Outputs 1 in both Chrome and FF
Surely the code should output 2? If I remove the var keyword from var x = 3, it outputs 2 as expected. Is there some strange compiler optimization at work here?
No, the code shouldn't output 2 because variable declarations are hoisted so your code is equivalent to
var x = 1;
(function() {
var x;
x = 2; // changes the internal x variable
return;
x = 3; // does nothing because it's not reached
})();
console.log(x); // Outputs the outside x, which is still 1
The line
x = 2;
only changes the internal x variable which shadows the outside one.
The scope of a non global variable is the entire function in which it is declared. From the start of this function to its end.
Consider the following two JavaScript snippets:
var x = 2;
function f() {
var y = x;
eval('var x;');
return y;
}
vs.
var x = 2;
function f() {
var y = x;
var x;
return y;
}
The only difference is I've replaced eval('var x;'); with var x;.
The first one returns 2, but the second one returns undefined. Why?
Variable declarations are hoisted by the parser to the top of the lexical scope. In the second block of code, the way it's actually run is:
function f() {
var x, y;
y = x;
return y;
}
Function declarations are also hoisted. The net effect is that a variable declaration should be considered to always include the entire lexical scope in which it appears. If variable x is declared with var anywhere in a function, then every reference to x in that function is to the local variable.
In your first example, the eval() line is just a regular expression statement, so it's executed in order of its appearance in the function.
Because with the second one, the var is hoisted* to the beginning of the function, before any other statements are executed.
So its as though you code was this:
var x = 2;
function f() {
var x, y
y = x;
return y;
}
But with the first one, the var x is part of the eval() expression, so it doesn't have the opportunity to be hoisted* as in the second one.
*The term "hoisted" is not an official term. Its just a word that people use to describe the fact that declarations happen before any expressions are evaluated within the execution context. Function declarations are also hoisted.
That's because when the interpreter is in scope of function it sets value undefined to all variables which are declared inside it (with var keyword prefixed). It's no matter where you've put the declaration, if there's a variable declaration inside a function the variable's value will be undefined until you set it's value explicitly. In the first case you have eval('var x;') which is still not evaluated when the value of y is being set. That's why the value of y is 2, because the value of the variable x in the upper scope is 2.
The same will be here:
var x = 2;
function foo() {
var y = x;
console.log(y); //undefined
console.log(x); //undefined
var x = 3;
}
function bar() {
var y = x;
console.log(y); //2
}
var x = 2;
function foobar() {
console.log(x); //undefined
var x;
console.log(x); // undefined
x = 3;
var y = x;
console.log(y); //3
}
The eval is evaluated just as a regular expression.