why is this a not defined when it clearly is? - javascript

I'm a total newbie, trying to survive my JS assignments. Any help is welcome.
When I run the following code, I get an error message saying "a is not defined." But a is defined.
function name(a, n) {
let a = b;
let b = x;
let c = n;
let b = c;
return c + a;
}
console.log(name(a, n));

a is only defined inside the function.
You are trying to read a (and n) outside the function and pass the resulting values to the function.

The problem is the way you call the function name instead of this console.log(name(a, n)); use this: console.log(name(5, 10));
As #Quentin said, when you pass the variables a and b to the function console log, it has to be defined outside of your function, but you can pass just the values and don't need to define the a and b variable outside the function.

So many problems here...
function name(a, n) {
let a = b; // a is already declared in function's declaration
let b = x; // x has never been declared
let c = n;
let b = c; // b is already declared in Line 3, additionally this line will make b = n
return n + a;
// this would finally become return b + b
// because Line 4: c = n
// and Line 5: b = c
// and Line 2: a = b
}
document.write(name(a,n)); // a and n should contain any value

Related

for loop function that returns sum [duplicate]

This question already has answers here:
Generating Fibonacci Sequence
(52 answers)
Closed 4 months ago.
I have a sequence that needs to be an output.. which is 8
so what i did (with a help of a friend of course.. bec i'm not smart and have adhd.. is this:
let a = 1;
let b = 1;
let c = a + b;
a = b; // 1
b = c; // 2
c = a + b; // 3
a = b; // a = 2
b = c; // b = 3
c = a + b; // 2 + 3 = 5 c = 5
what i need next, is to make a for loop, that will calculate it to 8 (perform the exact same calc task as above
(a = b and b = c and c = a + b)
to make the function get print an output of 8..
let a = 1;
let b = 1;
let c = a + b;
a = b; // 1
b = c; // 2
c = a + b; // 3
a = b; // a = 2
b = c; // b = 3
c = a + b; // 2 + 3 = 5 c = 5
function calc () {
for (let i=0; i<= ( ? ? ? ? ? ?); i++){
console.log(i);
}
}
calc()
function calc () {
for (let a = 0, b = 1, c = 0; c < 8;) {
c = a + b;
a = b;
b = c;
console.log(c);
}
}
calc();
does it work as you need?
The main idea here: in the loop you can use any variables to set initial state, increment and break condition.
UPDATE
The loop simply repeats what you've done without loop. Let's see where every part of your code goes.
Loop declaration contains 3 parts.
Initialization
let a = 1;
let b = 1;
I just updated a to be 0, not 1. So number 1 will be displayed in your console.
Exit condition.
As you described, loop should end when we reach 8. We increment the values inside the loop and then display it. So condition should be c < 8.
"Increment"
In your case it's
let c = a + b;
a = b; // 1
b = c; // 2
This block is repeated several times and contains more than 1 assignment. So we put it inside the block and leave the "increment" part empty.
It sounds like you're trying to output the Fibonacci sequence (1, 1, 2, 3, 5, 8, 13...) where each number in the sequence is the sum of the two previous numbers.
function calc() {
// We need to hard-code the first two numbers in the sequence to get started
let a = 1;
let b = 1;
console.log(a);
console.log(b);
// If we do 4 loops, the last value printed will be 8
for (let i = 0; i < 4; i++) {
let c = a + b
console.log(c);
// Shift a and b along the sequence
// a gets the value held by b, and b gets the value held by c
a = b
b = c
}
}
calc();
If you want it to only print out 8.
function calc() {
let a = 1;
let b = 1;
for (let i = 0; i < 4; i++) {
let c = a + b
a = b
b = c
}
console.log(b); // Prints 8
}
calc();
Yes, a Fibonacci series - what fun!
Here is a slightly condensed version of it with only two variabes (a and b):
function calc (max) {
for (let a = 0, b = 1; b < max;) console.log(([a,b] = [b,a+b])[1])
}
calc(100);
Update
Here a version that will only return the last two values (for later use in your HTML): the last one below and the first one above the target value max:
function calc (max) {
for (var a = 0, b = 1; b < max;) [a,b] = [b,a+b];
return [a,b];
}
console.log(calc(100));
Sorry for overloading you. I have to admit, I didn't carefully read all the text in your question. In particular your ADHD situation. No worries, I will try to explain what I did now in more detail so you will be able to follow:
1. My loop is set up in a for() loop - like in Alexey's solution:
for (var a = 0, b = 1; b < max;)
This means
that initially the variables a and b will be set upt to contain the values 0 and 1 (the two assignemts are separated by the ,-opertor).
The second part of the for expression (b < max) checks whether bis still below the maximum value max and only then will the loop expression be executed.
A third expression (behind the ;-separator) does not exist.
2. The loop expression ...
[a,b] = [b,a+b]
... makes use of the new ES6 feature of destructuring. It is a shorthand version of the otherwise three separate assignement statements:
tmp = b; // buffer the value of b
b = a+b; // do the sum and re-assign to b
a = tmp; // assign the original value of b to variable a
The ES6 construct is helpful here,
as it buffers the calculated results of the right hand side before assigning it to the array on the left hand side of the equation.
Only then (in the destructuring phase) will the newly calculated values be assigned to the variables a and b.
3. The return value(s)
As I was uncertain as to which value you wanted to have returned from the function I chose to return two values in an array: one below and one above the target value max.
return [a,b];
It is up to you to adapt the return statement to better suit your needs: either return a; or return b;.
4. var instead of let
Please note that I used var a=0, b=1 instead of let a=0, b=1 in the for() loop of my later version, as I needed to access these variables outside the scope of the for() loop. The var defines a variable with function scope (instead of block scope).
I hope that this will help you a little more than my admittedly fairly cryptic first version.
Alternative version (variation)
If you are looking for a function that will retun the n-th value of the Fibonacci series you can do it like this:
function fib (n) {
for (var a = 0, b = 1; n--;) [a,b] = [b,a+b];
return b;
}
// test the function fib with n = 1, ..., 19
for (let i=1; i<20; i++) console.log(`fib(${i}):`,fib(i));

Why var x = 5 work and not var n = a?

Why am I able to write:
var x = 5;
console.log(x);
5
but when I write:
var n = a;
console.log(n);
Uncaught ReferenceError: a is not defined
Well, you don't have a variable a. Set it beforehand, like this:
var a = 10;
var n = a; // n is now also 10
If you want a character string, enclose the characters in quotes:
var n = "a"; // n is now a character string, not a number
When you write
var n = a;
then it means to set n's value the same value as variable a. But you haven't defined a yet, so you get an error message.
I think you mean the string "a", so use that:
var n = "a";
console.log(n);
Because a is not a defined variable as the error clearly states.
If you want to set n to the character 'a', then you need to put it in either single or double quotes.
n = 'a';
or
n = "a";
to print a in console,
var n = "a";
console.log(n);
print some other variable
var a = 10;
var n = a;
console.log(n);
Because you are trying to print out put of n which reference value of a which is undefined variable.
You are getting error instead of undefined because javascript does not allow you assignment of undeclared variable

Variables equality

I'm unsure why example 1 don't give the same result as example 2.
Example 1:
var a = [1,6,2,4];
var b = [];
function minT(data){
var d = [];
d = data;
d.sort(function(a, b){return a-b});
return d;
};
b = minT(a)
console.log("b =" + b);
console.log("a =" + a);
Results:
b =1,2,4,6
a =1,2,4,6
Example2:
var a = [1,6,2,4];
var b = [];
function minT(data){
var d = [];
d = data.slice(0,10);
d.sort(function(a, b){return a-b});
return d;
};
b = minT(a)
console.log("b =" + b);
console.log("a =" + a);
Results:
b = 1,2,4,6
a = 1,6,2,4
Why does example 1 affect array a?
How can I write a function minT that does not affect array a. (without a slice inside the function)?
The reason why your first attempt sorts your a array also is because d = data; just copies the object reference, so both variables are pointing to the same location in memory.
When you do d = data.slice(0,10);, you're assigning the result of the slice operation to the d variable, which is a different object in memory than the data variable is pointing to.
Check out this book excerpt on the differences between value vs reference.
In example 1:
You have written d=data. It means that d is pointing to the element data. You have not just copied the values.
Example 2:
You have written d=data.slice(0,10). It actually copies the element of data rather than copying the address of data.
Now, to write the function minT without affecting data, and without using function data.slice(), you just need to replace the line data.slice() with your own simple code to copy element of one array to another.
Here's what I've done :
function minT(data){
var d = [];
for(var i=0;i<data.length;i++)
d[i]=data[i];
d.sort(function(a, b){return a-b});
return d;
};

How do I replace variables with values inside a stringified function (Javascript)?

Consider the following :
var a = 5;
var b = function ()
{
console.log (a + 5);
};
var c = b.toString();
after the above has been executed, c will be equal to :
"function ()
{
console.log (a + 5);
}"
How can I have c be equal to :
"function ()
{
console.log (5 + 5);
}"
instead?
I tried the following :
var a = 5;
var b = function ()
{
console.log ('<%a%>' + 5);
};
var c = b.toString().replace('<%a%>', a);
But the above obviously makes c equal to :
"function ()
{
console.log ('5' + 5);
}"
Is there some other way of achieving this (javascript + RegEx) without using libraries like underscore (with the known template function) ?
Basically I'm trying to come up with a neat function that will convert a function into a string while at the same time replacing all variables (that have a hardcoded value) present in that function with their respective values, without the use of any variables.
Thanks
You can fix your snippet by changing the first argument of .replace:
var a = 5;
var b = function ()
{
console.log ('<%a%>' + 5);
};
var c = b.toString().replace("'<%a%>'", a);
For more generic solution you may need smarter parser with syntactical analysis.

Expression value

I have these declarations:
var a;
var b = 1;
var c = 2;
var d = a || b, c;
d is 1 , so what is the meaning of the ,c in the expression?
The construct
var d=a||b, c;
does two things :
it declares d and assigns it the value a||b
it declares the c variable
As c was already declared, I'd say it's totally useless.
var d = a || b, c; simply means var d = a || b; var c; "comma" is used to separate multiple variables' declaration. Here ,c is not needed as var c = 2; is already defining c.
Your code is effectively interpreted like this:
var a; // Variable declarations are hoisted to top of scope
var b;
var c;
var d;
b = 1;
c = 2;
d = a || b;
So the final c declaration is doing nothing at all. Note that var x = y, z; is simply a variable statement that contains two declarations (one of which includes an assignment).

Categories

Resources