Does a function's name act as a variable? - javascript

I have a question about this code below:
function myfunc () {
return 2 + 2;
}
console.log(myfunc);
Does anyone know why, when we log 'myfunc' to the console, we get the entire function itself back? Or in other words, is 'myfunc' acting as a variable that holds the function's contents, or is it just referencing that function?
Because if I go ahead & add this to the code...
myfunc = undefined; //or any other value like myfunc = 20;
...then since myfunc's value is changed, I can no longer use it to invoke the function. So what is 'myfunc' really?

The answer is yes, a function declaration creates a symbol in the local function scope (or global scope if the declaration is in that context) that works exactly like a variable declared with var (though function declarations are hoisted above var declarations).
Now, a function expression like this:
var x = function helloWorld() { return "hello world"; };
does not create a local "helloWorld" symbol (except when it does). The value of a function expression is a reference to the created function, and that can be assigned to a variable just like any other value.

Related

Confused about javascript function expression

I just started to learn about javascript etc, and I get a project from my friend to take a look at it, and what I saw there is that they are using javascript functions all the time as a function expression, like this:
var a = function(Id) {
//Do something here
}
I could say like ok, they'r working like that and I'm gonna work like that also like robot, even if I don't understand why is that like that..
So I'm wondering what is this acctually, (in that code I posted above) is that function called "a" which is expecting 1 argument called "Id" in our case so I could call it on click of some button for example, or maybe this var a is acctually variable which is called "a" but it might be called as a function and acctually it is a javascript function?
This is little bit confusing me here, and I saw in this project that almost all javascrit functions are used like this, but is this a right approach or they should use named functions expression so it might look like this:
var a = function myFunction(Id) {
//Do something here
}
So what is this now ? I created function called myFunction which is expecting 1 argument called "Id" and it could be called on click by myFunction and also by calling "a" varible ? (if it is variable, or it is also function name or whatever)..
Thanks guys
Cheers
The key to understanding this is that, in JavaScript, functions are data, just like any other. So, if you are ok understanding this:
var x = 10;
If you were to try to get the value of x, you'd get 10:
console.log(x);
Then, understanding this isn't that much of a stretch:
var x = function(){
// do something
}
if you were to try to get the value here, you'd get the actual text of the function:
console.log(x); // function(){ // do something }
Since this last version retrieves a function, you could then invoke the function by simply appending () to the returned value, like this:
x(); // This would invoke the function stored in x
The alternative approach is with a "function declaration" which looks like this:
function x(){
// Do something
}
Here, there is no variable storing the function...x is the function and to invoke it, you'd do it directly:
x();
However, in JavaScript, all declarations are "hoisted" to the top of their enclosing scope, so this:
var x = function(){};
would cause the declaration of x to be hoisted, but not the value of x, while this:
function x(){ ...};
would cause the entire declaration to be hoisted.
The difference is that a declaration would allow you to invoke the function in code the precedes the actual declaration (since hoisting would cause the function to be read first) and with an expression, if you tried this, you would get an error stating that x is not a function.
Here's an example of this:
// Print the return value from runing the function who's name is "x".
// This will succeed even though we haven't even declared the function x yet becuase all
// declarations are hoisted to the top of their enclosing scope;
console.log(x());
// Print the return value from runing the function stored in the variable called "y":
// This will fail with an error stating that y is not a function because only the variable
// declaration (var y) is hoisted to the top of the enclosing scope, but not the value assigned to it.
console.log(y());
// This is a function "declaration" for a function who's name is "x"
function x(){
return "hello from function declaration x";
}
// This is a function expression being assigned as the data for a variable
var y = function(){
return "hello from function expression y";
}
Both are useful and often interchangeable, but hoisting causes differences in how (and when) you can call the function.

why does a variable need to be created in this closure

Hi I have the following closure
function createCounter() {
var numberOfCalls = 0;
return function() {
return ++numberOfCalls;
}
}
var fn = createCounter();
fn()
fn()
And I believe I understand about scope and the fact that the inner function keep the outer function's values after the outer one has returned.
What I don't understand is why I need to create this variable
var fn = createCounter()
and then invoke the variable fn() instead of initially invoking createCounter()
I saw that createCounter() just returns 'function()' instead of what has to be '1' and I don't understand why.
Thanks for the help. Read many tutorials still having problems with understanding this.
Please note: the question's isn't about how to make the code more eloquent or better, it's about understanding of what's been done
When createCounter is called it returns another function and that returned function is not evaluated unless you do so. Remember, in JavaScript functions are objects too. They can be the return value of a function.
So when you do this:
var fn = createCounter();
fn references only the function returned by createCounterfunction and not its evaluated value.
If you need to evaluate the function returned by createCounter try something like:
createCounter()();
This evaluates the returned function.
If you call it like this it will always return the same value as it creates a new numberOfCalls variable every time you call createCounter.
In Javascript, functions are objects which can be passed to and returned by other functions, as any other objects (e.g. a string, a number...).
So doing:
function foo(arg) { /* ... */ }
var someObject = new String("Hello");
foo(someObject);
is similar as:
function foo(arg) { /* ... */ }
var someFunction = new Function("Hello", "...");
foo(someFunction);
A function may thus return another function, which can be invoked as needed.
function foo() {
return new Function(...);
}
var functionReturnedByCallingFoo = foo();
functionReturnedByCallingFoo(); // can be invoked
functionReturnedByCallingFoo(); // and again
functionReturnedByCallingFoo(); // and again
Now, functions are almost never declared using the Function constructor, but rather with constructs named "function declarations" or "function expressions" - basically, the way we have defined the function "foo" in the previous examples, with a function signature and a function body delimited by curly brackets.
In such cases, the statements inside of the function body can read and write variables declared outside of the function itself ("free variables"), and not only variables declared within the function, as per the rules of lexical scoping. This is what we call a closure.
So in your case, the createCounter() function, when invoked, defines a local variable named "numberOfCalls", then return a function - the body of which having access to that variable. Executing the returned function changes the value of the variable, at each invocation, as it would for any "global" variable (i.e. variables declared in outer scopes).
Executing the createCounter() function many times would simply, each time, recreate a new local variable "numberOfCalls", initialize it to zero, and return a new function object having access to that variable.

Is this an anonymous function?

In the first snippet below, based on my understanding I am creating a function and assigning it to a variable. But does that mean the function will take that name of the variable ?
var aFunc = function(){};
I know this is named function.
function bFunc(){};
So, first of all we have to clarify the main difference between the two functions you wrote.
This one:
var aFunc = function(){};
is a function expression. Where this one:
function bFunc(){};
is a function declaration.
In a function expression you're using the function operator to defines a function inside an expression.
When you declare a function you're using the function statement.
At the beginning it can be confusing because they're really similar, however function declaration and function expression behaves differently. First of all, you can't declare a function that is anonymous: if you're using a function statement, the name is mandatory.
So only functions defined with the function operator can be anonymous:
var aFunc = function(){};
That's an anonymous function. In some browsers you can actually print the function's name and see by yourself:
console.log(aFunc.name);
(Notice that this is not standard yet, but there is a proposal)
But it doesn't means that functions declared with the function operator have to be anonymous. For instance:
var aFunc = function myFunction() {};
It's a named function. However, that's still different from having a function declaration like that:
function myFunction() {};
var aFunc = myFunction;
Why? Because in case of function expression, you don't declare a myFunction function in the scope:
var aFunc = function myFunction() {};
console.log(typeof myFunction) // undefined, unless some bugs
So what's the point to give a name to a function expression? The answer is: to have access from that function from the function's body itself, without pollute the scope. Imaging for instance you want to add an event listener to a DOM node, but execute the listener only once:
document.body.addEventListener("click", function onclick() {
// do something
document.body.removeEventListener("click", onclick, false);
}, false);
So you don't pollute the scope with a lot of functions that you use only for purpose like that ones, and you can still have access to the function from the function's body. That's especially useful in ES5 where arguments.callee is deprecated, and for recursion.
Another difference between function expression is that you can invoke them immediately, but you can't do that for function declaration. So, for instance:
function() {
console.log('foo');
}();
Will throw an exception, because the engine can't understand if it's a function declaration or a function expression. But if you force the engine to look at it as an expression:
!function() {
console.log('foo');
}();
// or
(function(){
console.log('foo');
}());
// etc, there are a lot of ways
Here we are: JS understand is an expression, therefore threats the function as an operator and not as a statement. And you obtain the IIFE (Immediately-Invoked Function Expression), that are useful in a lot of scenarios, specially where you want to isolate code.
So, back to you question, why the name of this function:
var aFunc = function(){};
is not aFunc?
Because, it's an expression. So the value knows nothing about the assignment on the left. It's like having:
var aFunc = -3;
Where the - is the Unary Negation operation and the 3 is the value: they knows nothing about aFunc, right? It's exactly the same with function expression, where function is the operator, and (){} is the value.
No.
In the first example you are creating an anonymous function and then assigning it to "aFunc"
In the second example you declare a function and call it bFunc.
The most notable difference between the two is that you can't call "aFunc" until after the line where you assign it.
No, the function will not "take the name of the variable". The variable will hold a reference to an anonymous function. The function itself is still anonymous.
Note that this makes little difference in the end though, this function reference can be treated exactly the same as any regular named function once it's assigned. In fact, it makes so little difference, a named function can be treated like a variable holding a function reference too:
function foo() { }
foo();
foo = 'bar';
alert(foo); // bar
The term "anonymous function" is jargon, so likely what it means will change over time. There is no specification that states what it is, so it can be whatever you want it to be. And whatever you decide will likely be disputed by someone else. Jargon is like that (look up the word "trunking", a common jargon term in telephony).
Strictly, there are function declarations where the name is mandatory, e.g.
function foo() {
...
}
and function expressions where the name is optional. If the name is missing, e.g.:
var x = function () {
...
};
then that, to me, is an anonymous function. If it has a name, e.g.
var x = function foo() {
...
};
then it's a named function expression (and not an anonymous function). From my perspective, any function expression without an optional name is an anonymous function. There are many uses for function expressions, e.g.
// assignment to a variable
var x = function() {...}
// pass as a parameter
foo(function(){...})
// immediately executed and pass the result
foo( (function(){...}()) )
and so on. So in the OP, the right hand side of the assignment is a function expression with no name so to me, that's an anonymous function. The fact that it's then assigned to an identifier doesn't suddenly make it a named function expression.
Others may differ of course.
Incidentally, the results of:
function foo(){}
and
var foo = function(){};
are practically indistinguishable, the main difference is when the functions are created.
No it is not. The right hand side of your first statement is a Function Expression. It is anonymous as long as you don't assign it to a variable.
After you have assigned it, you can use it as a declared function.
See more details about function declarations in this question

Javascript defining functions

I've been learning Javascript with Khan Academy. I'm looking at : http://www.khanacademy.org/cs/speed-circles/964929070
there is a line that reads "var draw = function() {...}" is he defining a function called draw? Or is the variable draw calling some function (which I don't see defined)?
Thanks!
Yes, a function expression is being assigned to the variable named draw. You can even call it:
var draw = function() {
console.log('xyz');
};
draw(); // 'xyz'
In JavaScript, functions are objects, just like arrays and -logically- objects are. As you may have found out already these objects can be assigned to a multitude of variables, but as soon as you change one of these variables, they all change. That's because JS always assigns by value, but a variable is never assigned an object directly: it's assigned a reference to an object:
var obj = {iam: 'an object'};
var reassign = obj;
console.log(obj);//shows object
console.log(reassign);//surprize, shows the same thing
reassign.bar = 'foobar';
console.log(obj.bar);//logs foobar, the variable obj has gained the same property, because it is the same object.
The same applies to functions, being objects, the can be assigned to variables/properties all over the place, but it'll still be the same object/function:
var foo = function()
{
console.log('I am an object');
};
var second = foo;
second();//logs I am an object
console.log(second === foo);//logs true, because they both reference the same thing
Why, then, you might ask is an anonymous function being assigned to a variable, instead of just declaring a function as you'd expect? Well:
function foo(){}
is hoisted, prior to running any code, JS moves all function declarations and variable declarations to the very top of the scope, but in your case, you're not simply defining a function, or declaring a variable: JS has to do something, too: assign a reference to a variable. The function won't be hoisted:
var foo = function()
{
console.log('foo');
};
foo();//logs foo
foo = function()
{
console.log('bar');
};
foo();//logs bar now
If foo were undefined prior to the assignment, you'd get an error. If any code preceded the code above, JS would hoist the variable declaration of foo, but it's value would still be undefined.
What's the point? This will prove useful when you start playing with closures, or if you need the function to differ, depending on a branch (if (x){ foo = functionX} else { foo = functionY;}). These are just 2 reasons why you'd want to avoid scope hoisting... but the most important reason of all ATM has to be redefining a function on the fly
Note that in processing.js (as used by this Khan academy demo), the function draw is automatically called every frame reference doc.
This bit of code overrides the default (empty) implementation of draw so that the given code is called every frame.
Khan academy has a tutorial about this use of the draw function here.
function draw(){ return "Sample"; };
var draw = function(){ return "Sample"; };
are same meaning.
function () { ... } creates a function value. That is, something that can be passed around just as easily as a number, or any other object in javascript.
He then binds it to the name draw for future reference.
He could as well have written
function draw() {
...
}
For these purposes they are equivalent.

Trying to figure out how scope works

I'm trying to learn JS on codeacademy and I can't understand/get past this thing. Can someone please provide an answer and also an explanation of why is it so? Would deeply appreciate.
// This function tries to set foo to be the
// value specified.
function setFoo(val) {
// foo is declared in a function. It is not
// accessible outside of the function.
var foo = val;
}
setFoo(10);
// Now that we are outside the function, foo is
// not defined and the program will crash! Fix this
// by moving the declaration of foo outside of the
// function. Make sure that setFoo will still update
// the value of foo.
alert(foo);
You can see scope as a term meaning what variables you can reach at a specific "level" in the code. In JavaScript, these "levels" are defined by functions. Each function introduces a new level.
For example, take this sample code:
var a;
// you can access a at this level
function function1() {
var b;
// you can access a, b at this level
function function2() {
var c;
// you can access a, b, c at this level
}
}
So in your case, you should declare var foo; outside the function, preferably above it. Then you can set it inside setFoo with foo = val;. foo then refers to the one you declared in the level above setFoo.
foo is accessible both in setFoo and in the alert call that way; compare it with the above sample code (function1 is setFoo, a is foo and the alert call is in the top-most level. function2, b and c are not used in your case.).
// Create globale variable
// (You should not use globale variables!)
var foo;
// set value
function setFoo(val) {
foo = val;
}
setFoo(10);
// show value
alert(foo);
Just declare foo outside any function then it will be global:
var foo = null;
function setFoo(val) {
foo = val;
}
setFoo(10);
alert(foo);
Try it !
When you declare a variable in Javascript it is only visible to code that is in the same function as it is declared, or a function inernal to that function. Because foo is originally declared in the SetFoo function nothing outside of SetFoo is able to see it, so the call to alert fails as foo does not exist in the gloabl scope.
As the comments suggest, moving the declaration of foo out of the function and into the global scope (which you can think of as a catch-all function that contains everything) would allow you to use foo when calling alert.
var foo;
function setFoo(val) {
foo = val;
}
setFoo(10);
alert(foo); // No longer crashes
Every function in Javascript has it's own scope. That means that every variable you define there with the var keyword, will only be available within that function. That means that when you call setFoo(10), you create the variable foo, give it a value of five, after which it is immediately destroyed because it went out of scope.
There are multiple ways to solve this problem. The first would be to remove the var keyword. This would put foo in the global scope, which means that it's available everywhere. However, this is discouraged, you want to keep the global scope as uncluttered as possible, so that if you have javascript code provided by multiple people on the same page, they can't overwrite other people's variables. Another way to do it would be this:
function setFoo(val){
var foo = val;
alertfoo = function(){
alert(foo)
}
}
In this example, the only thing you're putting in the global scope is the alertfoo function, because you want that to be available everywhere. The alertfoo function is defined inside the setFoo function, this means that although foo should have gone out of scope after setfoo has been executed, it is kept in memory, because alertfoo has access to it.
This makes for some nice tricks. For example, let's say you're making a javascript library that will be included on other people's pages, you'll want to create a scope inside of which you can define variables, without polluting the global scope. The most common way to do this, is by declairing a self-executing function. This is a function which is executed immediately after being defined, it looks like this:
(function(){
//set variables you want to be global in your own code
var mainpage = document.getElementById('main');
//define functions you want to make available to other people in a way that puts them in the global scope
setMainElement = function(newmain){mainpage = newmain;}
})();
You can make this even better by making only one object global, and provide your interfae through the methods of that object, this way, you create a namespace with all the functions that your library contains. The next example uses an object literal to do this. In javascript, you can create an object by putting key/value pairs petween curly braces. the key/value pairs are properties of the object. for example:
(function(){
var privatevar = 10,otherprivate=20;
publicInterface = {
'addToPrivate': function(x){privatevar+=x;},
'getPrivate': function(){return private}
};
})();
Original code:
function setFoo(val) {
var foo = val;
}
setFoo(10);
alert(foo); // Crash!
Their advice to fix the crash:
Fix this by moving the declaration of foo outside of the function
I'm guessing you're confused as to what they mean by "outside of the function".
Try this edited code:
var foo = 5; // "var" declares the variable to be in this outer scope
function setFoo(val) {
foo = val; // but we can still access it in this inner scope...
}
setFoo(10);
alert(foo); // Displays a dialog box that says "10"
Variables defined in the function is valid only in the function
function setFoo(val) {
foo = val;
}
In JavaScript, new scopes are only created by functions

Categories

Resources