How can I use variable in method function? (JavaScript) - javascript

let newArr = 0;
function solution(arr) {
for (let i = 0; i < arr.length; i++) {
newArr += arr[i];
}
}
console.log(solution([1,2,3,4])) //undefined ;
I want to add all of arrays. But error says, 'newArr' is assigned a value but never used.
How can I use variable in method function?
I tried to declare variable in method.
function solution(arr) {
for (let i = 0; i < arr.length; i++) {
let newArr = 0;
newArr += arr[i];
}
}
Of course it didn't work :(

Minimal changes, return newArr, though this isn't the cleanest solution
let newArr = 0;
function solution(arr) {
for (let i = 0; i < arr.length; i++) {
newArr += arr[i];
}
return newArr // add this line
}
console.log(solution([1,2,3,4]))
Alternatively, call the function (without a return) then output newArr because the function is changing its value. Global variables like this are generally not good practice, but it does depend on the situation
let newArr = 0;
function solution(arr) {
for (let i = 0; i < arr.length; i++) {
newArr += arr[i];
}
}
solution([1,2,3,4]) // call function
console.log(newArr) // output the value
Define newArr in the function and return it
function solution(arr) {
let newArr = 0; // define local variable
for (let i = 0; i < arr.length; i++) {
newArr += arr[i];
}
return newArr // return value
}
console.log(solution([1, 2, 3, 4]))
// console.log(newArr) // would be undefined

Hi #Josh Yeom,
The newArr variable is declared inside the solution function. So, guess what, it is only accessible within that function. The Value of newArr outside the function you can't use, because it's not in the same scope.
It's a concept of lexical scoping.
The scope of a variable is determined by its position in the code. Variables that are declared inside a block of code, such as a function or loop, are only accessible within that block. This is known as lexical scoping.
Or in other words.
Lexical scoping is a way of determining the accessibility of variables in a program based on their position in the code. It is a fundamental concept in many programming languages, including JavaScript.
In your case, need to do your code like this.
function solution(arr) {
let newArr = 0;
for (let i = 0; i < arr.length; i++) {
newArr += arr[i];
}
return newArr;
}
console.log(solution([1,2,3,4])) // 10
The newArr variable is declared outside the for loop, so it is accessible throughout the function. The value of newArr is then returned from the function using the return statement, and you can access this value by calling the solution function.
Here is a simple example of how lexical scoping works in JavaScript.
let globalVariable = "I am a global variable";
function outerFunction() {
let outerVariable = "I am an outer variable";
function innerFunction() {
let innerVariable = "I am an inner variable";
console.log(innerVariable); // "I am an inner variable"
console.log(outerVariable); // "I am an outer variable"
console.log(globalVariable); // "I am a global variable"
}
console.log(innerVariable); // ReferenceError:innerVariable is not defined
console.log(outerVariable); // "I am an outer variable"
console.log(globalVariable); // "I am a global variable"
}
console.log(innerVariable); // ReferenceError: innerVariable is not defined
console.log(outerVariable); // ReferenceError: outerVariable is not defined
console.log(globalVariable); // "I am a global variable"

That is because your function does not return the calculated value after completion.
let newArr = 0;
function solution(arr) {
for (let i = 0; i < arr.length; i++) {
newArr += arr[i];
}
return newArr;
}
console.log(solution([1,2,3,4]));

function doesn't have return value like you have to check then put console inside that function
For Exa
let newArr = 0;
function solution(arr) {
for (let i = 0; i < arr.length; i++) {
newArr += arr[i];
}
return newArr;
}
console.log(solution([1,2,3,4]))

Related

Not being able to reference a variable from outside the loop

Iam not able to reference a variable from outside the loop in the following function. I want to use the value inside the function itself but the scope doesnt seem to allow it.
function coinOnTheTable(m, k, board) {
for (var i = 0; i < board.length; i++) {
for (var j = 0; j < m; j++) {
if (board[i][j] === "*") {
const a = `${i}${j}`;
return a;
}
}
}
}
Works, While
function coinOnTheTable(m, k, board) {
for (var i = 0; i < board.length; i++) {
for (var j = 0; j < m; j++) {
if (board[i][j] === "*") {
const a = `${i}${j}`;
}
}
}
return a;
}
gives an error
return a;
^
ReferenceError: a is not defined
That's because a variable defined as const or let has "block scope". That means it is only visible inside the nearest set of curly braces. So:
function foo() {
const foo = 'foo-string';
if(1) {
const bar = 'bar-string';
console.log(bar); // This is fine
}
console.log(foo); // This is also fine
console.log(bar); // Error!
}
To solve your problem, you need to define your variable outside of the block defined by the nested for loop. So:
function coinOnTheTable(m, k, board) {
let a;
for(var i = 0; i < board.length; i++){
for(var j = 0; j < m; j++){
if(board[i][j] === "*"){
a = `${i}${j}`;
}
}
}
return a;
}
Note, the reason it changes from const to let is because const variables cannot be reassigned, but since you want to declare it as undefined (at the start of the function, then assign a string to it (inside the loop), you need to be able to reassign it.
make a function scope:
function coinOnTheTable(m, k, board) {
let a;
for(var i=0;i<board.length;i++){
for(var j=0;j<m;j++){
if(board[i][j]==="*"){
const a=`${i}${j}`;
}
}
}
return a;
}

When I use for loop in JavaScript, Is exist all value in memory?

As I was studying closures and local variables,
I was curious to see the example below.
function myLoop() {
var result = [], i, n = 4;
for (i = 0; i < n; i++) {
result[i] = function () {
return i;
}
}
return result;
}
var l = myLoop();
var f = l[0];
console.log(f()); // undefined
I recently knew how variable allocate.
Point to a value, not a allocate.
if I declare variable,
I allocated 'string'.
and I again allocated another string
var str = 'hello';
str = 'world';
and
str -> hello,
str -> world
Because 'String' is immutable.
Result
In conclusion, I wonder what is the status in memory?
i of 'for loop' exist all value in memory?
i -> 0,
i -> 1,
i -> 2,
i -> 3
or
i = 1(..3,4) allocate?
In this case, you only have a single binding for i, one which is declared at the beginning of myLoop. Every array item in result has a function which points to that singular i. So, when myLoop returns, you've created an array of functions, all of which reference a single value, the i whose value is 4:
function myLoop() {
var result = [], i, n = 4;
for (i = 0; i < n; i++) {
result[i] = function () {
return i;
}
}
return result;
}
const arr = myLoop();
console.log(
arr[0](),
arr[1]()
);
This value will eventually be garbage collected (the variable name's link to the value it contains) once nothing can reference the arr or any of its functions anymore.
If you had used let in the for loop instead of var, you would have a separate binding for i on each iteration:
function myLoop() {
var result = [], n = 4;
for (let i = 0; i < n; i++) {
result[i] = function () {
return i;
}
}
return result;
}
const arr = myLoop();
console.log(
arr[0](),
arr[1]()
);
in which case, every iteration of the for loop would have its own i value, so there'd be 4 separate values for i in memory at the time myLoop returns. Just like above, those 4 values will continue to exist until nothing can reference them anymore, and they get garbage collected.
(Technically, there'd also be another temporary binding or two for i for the duration of the loop, created by the for loop due to the mechanics of let loop declarations, but it's near invisible to scripts and is more confusing than useful to think about in this situation)

Scope and accessing outside variables in anonymous functions?

I'm sure I'm doing something dumb here, but I'm not sure what. I'm adding anonymous functions to an array for later execution, and creating them in a for loop with variables that change each iteration.
I'm expecting the logged values to be:
https:server.net/a
https:server.net/b
but instead I'm getting:
https:server.net/b
https:server.net/b
It looks like maybe when I redefine the function it overwrites the last version of it, but I'm not sure why. I would think that each anonymous function would be different.
Why? What am I doing wrong here?
Here's some sample code:
f = [];
items = ['a', 'b'];
for(var i = 0; i < items.length; i++){
var itemID = items[i];
var itemAccessUrl = `https://server.net/${itemID}`;
var func = function(){
console.log(itemAccessUrl);
};
f.push(func);
}
console.log(f.length);
for(var j = 0; j < f.length; j++){
func();
}
This is because of the nature of var scoping. var is not block scoped, it is "hoisted", as if you declared it at the top of your function.
You could declare itemAccessUrl using let instead of var, which is block scoped, but it depends on what browser support you require. (Having said that, you're using templated strings, so you should be fine)
What's happening here? When you invoke your array's functions, they use the current value of itemAccessUrl, i.e. the last assigned string, with char 'b'. This because their invocation happens after the completion of first for-loop.
You can use a closure:
f = [];
items = ['a', 'b'];
for(var i = 0; i < items.length; i++){
var itemID = items[i];
var itemAccessUrl = `https://server.net/${itemID}`;
var func = (function(param) {
return function () {
console.log(param);
};
})(itemAccessUrl);
f.push(func);
}
console.log(f.length);
for(var j = 0; j < f.length; j++){
f[j]();
}
or bind your function to current param:
f = [];
items = ['a', 'b'];
for(var i = 0; i < items.length; i++){
var itemID = items[i];
var itemAccessUrl = `https://server.net/${itemID}`;
var func = (function (param) {
console.log(param);
}).bind(null, itemAccessUrl);
f.push(func);
}
console.log(f.length);
for(var j = 0; j < f.length; j++){
f[j]();
}
Furthermore you have to change the second loop, invoking f[j]();

Javascript - Index inside a for reader into a for inside a function, is it possible?

javascript:
for (i = 0; i < n; i++)
{
v = fn(obj);
}
function fn(o)
{
for(i = 0; i < o.length; i++)
{
...
}
}
The first index get modify from second FOR inside the function fn(o);
How is it possible? what's the scope of index?
It doesn't look like you're declaring i as a local variable, so what's happening is that i being treated as a global variable. You need to write the var keyword in order for a variable to become a local variable.
for (var i = 0; i < n; i++)
{
v = fn(obj);
}
function fn(o)
{
for(var i = 0; i < o.length; i++)
{
}
}
I don't see any var so it looks like you're not varing anything, but I'll add those in and answer the question
Is it possible to modify the i in one for loop from another in a different scope?
When using functions in JavaScript, all primitive arguments are passed ByVal and all object arguments are passed ByRef. This also happens when using =.
Therefore, if you want to modify i out-of-scope, you will need to always access it through an Object.
function foo() { // scope this away from fn
for (var c = {i: 0}; c.i < n; c.i++) { // i wrapped in object
v = fn(obj, c); // pass wrapping object into `fn`, too. Now see `fn`
// c.i is now the result of change in `fn`
}
}
function fn(o, c) {
for(var i = 0; i < o.length; i++) {
// ...
}
// make change to c.i
c.i = 0;
}
foo();

Closure confusion

I am having some confusion regarding this Closure thing. I have two separate codes below that look similar but their output are different.
function setup(x) {
var array = [];
for(var i=0;i<arguments.length;i++){
array[i]= arguments[i];
}
return array;
}
console.log(setup('a','b')); // will output ["a","b"]
--------------
function f() {
var i, array = [];
for(i = 0; i < 3; i++) {
array[i] = function(){
return i;
}
}
return array;
}
var a = f();
console.log(a()); //output: [function(),function(),function()]
console.log(a[0]()); //output: 3 //same output in a[1]() and a[2]() calls as well
Now my question is, how come the output is different? both of the codes above return an array. in the first code, it prints all elements in array correctly whereas in the second code, why doesn't it print [1,2,3]???
In your second example, you are creating 3 function in a loop, but all the functions are created in the same variable scope, so they all reference and return the value of the same i variable.
Therefore the value of i returned from the functions represents the value at the time when the functions are invoked. Because you're invoking them after the loop, the value of i is 3, so that's the value returned.
This is what is meant by closure. The functions "close over" the variables that existed in the variable scope where they were created. They do not close over the value of the variables, but rather then variables themselves, so they always get the current state of the variable.
For each function to reference a different value of i, each function would need to need to be created in a separate variable scope that has its own unique i.
Because the only way to create a new variable scope in JavaScript is to invoke a function, you'll need to create each function within a new function invocation.
function makeFunction(j) {
return function(){
return j;
};
}
function f() {
var i, array = [];
for(i = 0; i < 3; i++) {
array[i] = makeFunction(i);
}
return array;
}
So here I made a new function called makeFunction. It receives a single parameter, and returns a new function that references and returns that parameter.
Because each invocation of makeFunction creates a new and unique variable scope, each function returned will be referencing its own unique j variable, and will therefore return the value of j that existed when makeFunction was invoked (unless your function modifies j, which it could do if you wanted).
Note that I used the variable name j for clarity. You could use i as well, or some other name.
In JavaScript, you have function statements and function expressions. The first declare named functions, the latter evaluate to a named or anonymous function. You're using a function expression.
What I think you want to do is a call expression. All you have to do is to immediately call your function that returns i.
function f() {
var i, array = [];
for (i = 0; i < 3; i++) {
// The extra parentheses around the function are unnecessary here.
// But this is more idiomatic, as it shares syntax with how function
// expressions are introduced in statements.
// I.e. you could just copy-paste it anywhere.
array[i] = (function () {
return i;
})(); // don't rely on automatic semicolon insertion
}
return array;
}
Also note that, in your problematic example, all closures return 3 because all of them capture the same variable i.
EDIT: To make the previous paragraph more clear, if you really wanted to have 3 distinct closures, you'd have to create a new scope for each one. Unlike other languages, Javascript doesn't create scope just by opening a block. It only creates scope in functions. Here are two ways of doing this:
function f() {
var i, array = [];
for (i = 0; i < 3; i++) {
// With a parameter in an inner function
array[i] = (function (n) {
return function () {
// A new n is captured every time
return n;
};
})(i);
}
return array;
}
function f() {
var i, array = [];
for (i = 0; i < 3; i++) {
array[i] = (function () {
// With a variable in an inner function
var n = i;
return function () {
// A new n is captured every time
return n;
};
})();
}
return array;
}
The next example, however, is wrong, because even though n is declared in the for block, it will be as if it has been declared at the top of the function and only initialized in the for block. Remember, this is JavaScript, not Java, not C, not C#, not <whatever bracketed language>:
function f() {
var i, array = [];
for (i = 0; i < 3; i++) {
var n = i;
array[i] = function () {
return n;
};
}
return array;
}
Equivalent code:
function f() {
var i, array = [];
var n;
for (i = 0; i < 3; i++) {
n = i;
array[i] = function () {
return n;
};
}
return array;
}

Categories