Is function scope variable not writable - javascript

function add() {
var counter = 0;
counter += 1;
return counter
}
Why the counter variable dont get incremented after first iteration? output is always 1.

The addfunction is returning the variable counter which is defined inside the function add. The scope of variable counter is local to function, which means each time you invoke the function, it creates a new variable counter and then initialize to zero and then increment the counter.
If you are looking for a counter implementation, then you need to reference the same counter variable every time and increment that variable. This can be implemented by using closure.
Example: In the below example, there are 2 functions, 1 nested inside the another one. The inner function maintains a reference to the outer function Environment, which in this case contains the counter variable. So, even after the control moves out of the function add, the inner functions maintains a reference to counter variable.
var add = (function(){
var counter = 0;
return function(){
return ++counter;
}
})();
document
.querySelector('#btn')
.addEventListener('click', function(){
document.querySelector('#output').textContent = add();
});
<div id="output">0</div>
<button id="btn">Increment</button>

This is a scoping issue. Change it to
let counter = 0;
function add() {
counter += 1;
return counter
}
Or if you want to be able to do add(), use a nested function
function adder() {
let counter = 0;
return function plus() {
return counter += 1;
};
}
let add = adder();
console.log(add());
console.log(add());
console.log(add());

You can make the counter a global variable and then call the add function:
function add(){
counter = counter + 1;
}

Related

What is the reason for the ratio of the function to a variable?

this not work
function myCounter(){
let counter = 0;
function plus(){
counter++;
return counter;
}
return plus;
}
console.log(myCounter());
console.log(myCounter());
but this work
function myCounter(){
let counter = 0;
function plus(){
counter++;
return counter;
}
return plus;
}
var add = myCounter();
console.log(add());
I know they are different in the syntax.
My main question is:
Why function alone on the console.log does not work and should be attributed to a variable
Your function myCounter only returns a function reference. It does not call the function plus.
In your first example you only call the function myCounter:
console.log(myCounter());
In your second example you first call the function myCounter that returns a function reference:
var add = myCounter();
and then you call the returned function:
console.log(add());
Solution:
You have to change this line
return plus;
to
return plus();
This works:
function myCounter(){
let counter = 0;
function plus(){
counter++;
return counter;
}
return plus();
}
console.log(myCounter());
You are missing the closure concept. Calling a myCounter function will return you another function and it will initialize "private" variable counter inside, so myCounter() -> function.
Of course you can call this way myCounter()(), but in this case the "private" counter variable will be initialized every call with value 0, and won't be useful.
The solution is to store result of myCounter() in variable and call it later, so you will have expected behaviour.
function myCounter(){
let counter = 0;
function plus(){
counter++;
return counter;
}
return plus;
}
console.log(myCounter()());
console.log(myCounter()());
console.log(myCounter()());
console.log('====')
var add = myCounter();
console.log(add());
console.log(add());
console.log(add());
In the second example this line: var add = myCounter(); makes the add var to be only a reference to a function, if you will console log the add var without the brackets, it will print only [Function], but the console.log(add()); makes the add function to be invoked.
In order to make the first example to work, you can change the return statement of the myCounter counter function.
This code make the myCounter to return only the plus function reference:
function myCounter(){
function plus(){
//code
}
return plus;
}
So in order to make it work you should invoke the myCounter twice:
console.log(myCounter()());
But this make the plus function to be invoked when the myCounter is invoked (called) from inside the console.log(myCounter()):
function myCounter(){
function plus(){
//code
}
return plus();
}

Why is this function returning a function?

Why am I assigning counter function to count variable? And what is the purpose?
function counter() {
var localVar = 0;
return function() {
localVar++;
return localVar;
}
}
var count = counter(); // I am confused here.
console.log(count());
counter is a function-factory, it returns a function when called.
By assigning a variable to counter you can keep track of this counter and every time you call it the variable localVar will get incremented by one, if you were to always call counter()() you couldn't keep track of that value.
Example:
function counter() {
var localVar = 0;
return function() {
localVar++;
return localVar;
}
}
var count = counter();
for(var i = 0; i<99; i++) count();
console.log(count()); // 100
for(var i = 0; i<99; i++) counter()();
console.log(counter()()); // 1
You aren't assigning the counter function to a variable, you're calling counter and assigning what it returns to the variable.
It's just that counter returns another function.
Note inside counter, there's the bit:
return function() {
localVar++;
return localVar;
}
Which can literally be read as "return a function that increments a local variable, then returns the current state of that variable".
The function counter is a function factory, which is a function that returns a new function—which, in this case, is a function that increments a value.
This new function is then assigned to the variable count.
The usefulness of this pattern is that functions have access to their local scope. So, that function can access and increment the variable localVar in its scope—which is also declared when counter is called—, and no outside functions can modify it, so there are no conflicts of multiple functions changing the same variable. Also, this way you can have multiple counters that don't conflict with each other.
The reason for this is you can use a counter on whatever variable you assign it to so you can keep multiple instances that all keep track independent of one another.
See example below:
function counter() {
var localVar = 0;
return function() {
localVar++;
return localVar;
}
}
var count = counter();
var secCount = counter();
console.log(`count: ${count()}`);
console.log(`count: ${count()}`);
console.log(`secCount: ${secCount()}`);
console.log(`secCount: ${secCount()}`);
console.log(`count: ${count()}`);
console.log(`count: ${count()}`);
console.log(`secCount: ${secCount()}`);
console.log(`secCount: ${secCount()}`);
console.log(`count: ${count()}`);

javascript calling a inner function from outside

This is regarding javascript closures working.
I have a function inside another and I want to access this outside of the outer function.
is it possible since it written here that u can achieve closure with this
http://www.w3schools.com/js/js_function_closures.asp
JavaScript Nested Functions
All functions have access to the global scope.
In fact, in JavaScript, all functions have access to the scope "above" them.
JavaScript supports nested functions. Nested functions have access to the scope "above" them.
In this example, the inner function plus() has access to the counter variable in the parent function:
Example
function add() {
var counter = 0;`enter code here`
function plus() {counter += 1;}
plus();
return counter;
}
I am trying to acess plus() from outside
Agree with Grim.
But if you wanna access to plus function outside, you can try this way:
function add(){
var counter = {
value: 0,
plus: function(){
return ++this.value;
}
};
counter.plus();
return counter;
}
Hope it helps.
You cannot. An inner function is only available within the body of the outer function.
I assume your target is to keep value as private property inside add and provide manipulations to it via add.plus() calls:
//define your object with a private "value" and a public modifier "plus"
var add = (function() {
var counter = 0;
var that = {
plus: function() {
return counter++; //equal to your code
}
}
//your integrated first call
that.plus();
return that;
})();
//make a call
add.plus();
DEMO - Working code example.
This may be what you are looking for, especially as related to the tutorial link you provided. It is a step in the right direction.
var plus;
add();
plus();
plus();
plus();
alert(plus());
function add() {
var counter = 0;
plus = (function(counter) {
return function() {counter += 1;return counter;};
})(counter);
plus();
}
It is a straight forward example of closure. I made plus a global variable, but alternatively add() could return the function definition of plus. I took the return value away from add() and moved it to plus(), as with this code counter will always equal 1 when add() is finished.
However, and directly from the tutorial you mentioned, the best way to achieve what they are attempting is with this code, ripped directly from their web page.
var add = (function () {
var counter = 0;
return function () {return counter += 1;}
})();
add();
add();
add(); // the counter is now 3

Increment value each time when you run function

So I need a function which increments the value of a variable say n=0. When ever the function runs, the value of this varible must be incremented and it should not be equal to 0 again. For example consider the following code :
function increment(){
var n = 0;
n++;
return n;
}
Now everytime you run this function you get a value of 1. But my requirement is if you run this function for the 1st time, it should be 1, if you run it for the second time, it should be 2 and so on. Unless you refresh the html page and run the function again, it should not be equal to 0. Can anybody help me?
I'm new to coding and any small help is appreciated. Thanks in advance!!!
Create a closure to hold the value
Closures are functions that refer to independent (free) variables.
In short, variables from the parent function of the closure remain bound from the parent's scope.
var increment = (function(n) {
return function() {
n += 1;
return n;
}
}(0)); // -1 if you want the first increment to return 0
console.log(increment());
console.log(increment());
console.log(increment());
You need to declare n outside of the function.
var n = 0;
function increment(){
n++;
return n;
}
The problem is scopes. when you declare a variable inside of a function it is bound to the local scope of the function. as soon as the function is done the variable is gone.
declaring the variable in the root level of the script places it in the global scope.
another way to do this would be to have a variable outside that you're passing around and then you pass it to the function via a parameter.
var i = 0;
function increment(n){
n++;
return n;
}
i=increment(i);
for more information on scopes and variables, review this page: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Values,_variables,_and_literals#Variable_scope
You can bind the data to the function (since functions are objects).
function increment(){
increment.n = increment.n || 0;
return ++increment.n;
}
What about making the number of times increment was called a parameter ?
function increment(numberOfIncrementCalls){
numberOfIncrementCalls++;
return numberOfIncrementCalls;
}
function increment(numberOfIncrementCalls){
numberOfIncrementCalls++;
return numberOfIncrementCalls;
}
n = document.getElementById("demo");
o = document.getElementById("event");
numOfIncr = 0;
o.addEventListener("click",function(){
numOfIncr = increment(numOfIncr);
var insert = numOfIncr.toString();
n.innerHTML = insert;
});
<html>
<p id="demo"></p>
<button id="event">Click me</button>
</html>
var n = 0;
function increment(){
n++;
return n;
}
Learning about scopes will help you greatly. What you want here is the variable 'n' to be of a global scope.
var n = 0; //Declare n outside of the function makes it accessible to the function
//and to any other functions or expressions that want access to n
function inc() {
n++;
}
You can try this code and store the value in localstorage. All time it will be increase old Value untill you have not clear localstorage...
<script>
localStorage.setItem("n", 0);
increment();
function increment(){
let n;
n = localStorage.getItem('n');
n++;
localStorage.setItem("n", n);
return n;
}
</script>
Every time you call a function the value will be incremented by +1 by this method --
let x = 0;
function increment (){
return x = x + 1;
}
This code will always return 501
a=500;
function increment(n){
return n+1
}
increment(a);
You could equate a to the function
a=increment(a);
That would set a to 501, then 502 etc
However consider using an array for the argument instead
a=[500];
function increment(n){
n[0]++;
}
increment(a);
Now it will increment the value of a[0] even though it doesn't have a return statement. The benefit of this is it means we can have multiple arguments and increment them all, and then return some other variable if you like. Like this
a=[0];
b=[5];
function incrementToTen(n,o)
{
n[0]++;
o[0]++;
if(n[0]>=10||o[0]>=10)
{
return true;
}
else
{
return false;
}
}
So after running incrementToTen(a,b) 5 times it will return true

Set value of counter function

The following code will allow the counter function to be incremented by one every time counter(); is called.
function One() {
var counter = function(initial) {
var c = initial || 0;
return function() {
return c++;
};
}(0);
Too(counter);
}
function Too(counterArg) {
counter();
}
Is there any thing I can replace counter(); with so the counter will decrement? Or even better is there any way for me to set the value of the counter? Like counter = 0 or counter = 20? Also I need to stay away from global variables.
you can assign function as a variable in javascript so now you can do this...
var counter = 0;
var step = 1; // or 20 or whatever
var method = null;
function increment () {
counter += step;
}
function decrement () {
counter -= step;
}
method = icrement;
method();
First, you have a minor typo in your code; presumably you mean
function Too(counterArg) {
counterArg(); // this was just `counter` originally; that will be undefined
}
Second, c++ is a little bit of a weird way to do a counter, since it return c and then increment c, so the counter will start at 0 which is probably not what you want.
(I admit I chuckle a little bit whenever I see c++ in code though. :P )
Okay, on to the main question: I'd do it by adding a method to the counter function called e.g. set.
function One() {
var counter = function createCounter(initial) {
var c = initial || 0;
function counter() {
return ++c;
}
counter.set = function(n) {
c = n;
};
return counter;
}(0);
Too(counter);
}
function Too(counterArg) {
counter(); // 1
counter.set(20); // `c` is now 20
counter(); // 21
counter(); // 22
}
This works because the counter function creates what's called a closure. This is a fairly common concept in JavaScript and there are plenty of good questions and answers about closures on SO that you should look at if you don't know the concept. Basically, even after your anonymous function (which I renamed createCounter) returns, the variable c still exists and can be accessed from any code in createCounter. That's how the counter function works. c cannot, however, be accessed by any code outside createCounter, so if you want to do anything with it, you have to put that code in createCounter. That's what the counter.set method I added does. Since it's within createCounter, it is free to modify c.

Categories