Function parameter scope in javascript - javascript

What is the scope of function parameter in Javascript
var greetFunc = function(name){
var something;
}
console.log("Hello" +name);
console.log(something);
I understand the scope of something is just inside the function, it will not exist outside that.
But what about name. Why the value is blank for name variable.

Referencing name outside the function doesn't throw an error like you would expect because it is actually a global variable in every page, part of the global window object. Typing name is the same as window.name.
The something variable causes an error because it hasn't been defined yet. However, the name variable doesn't cause any problems because it is blank by default, at least in Chrome. You are correct that variables created in a function don't exist outside it.
See https://developer.mozilla.org/en-US/docs/Web/API/Window/name for details.

The parameter name is similar to declaring a variable name at the top of the function.
So the scope of a parameter is the function it is a part of.

Related

Why variables of function declared outside through "." accessible only through "." inside the function?

I initialized a variable of function through "." outside the function. Regarding closure rule, it should be set inside the function scope and after execution should be gone. But
Why after calling the function variable still exists?
Why can I access inside a function only through "."?
I initialized variable outside of the function through "." like f1.a = "any variable".
I checked if the variable of function initialized outside is accessible inside a function without ".":
I tried to get access to the variable inside the function. It seems if I get access to the variable by itself without "." it gives me an error "variable is not defined".
I checked if the variable of function initialized outside will be gone after function execution:
I call function and check if the value of the variable after execution is still available. Yes, it was still there.
f1.a = "any variable";
function f1(){
(function()
{
console.log(a);
}()) // a is not defined
}
f1();
console.log(f1.a); // after f1(), f1.a still exist
I expected variable "a" visible by itself inside the "f1" since I initialized inside the function scope f1.a = "any variable", but I can get access only with "."
I expected variable "a" will be gone after execution f1(), but it still exists
There are several things you need to understand to get a clear idea of what's happening here. First, JavaScript hoists function definitions to the top of the file.
Knowing that, you could imagine your code is something like this once JavaScript interprets it:
var f1 = function (){
(function()
{
console.log(a);
}()) // a is not defined
}
f1.a = "any variable"
f1();
console.log(f1.a);
Secondly, in your first console.log(a) you are referencing a variable a which was never declared. If you change that to console.log(f1.a) you'll see the value of f1.a as expected.
It's also not clear why you are using an immediately invoked function inside of your f1 function. It makes analyzing this code even more complex. It seems like you are trying to get a better understanding of how closures work? But for closures you should be interested in variables declared inside of f1, rather than properties of f1. For example, something like this.
f1 = function (){
var a = 'something'
return function()
{
console.log(a);
}
}
var closure = f1();
// f1 is finished running here.
closure(); // closure still has access to f1's variable.
I think the three areas you could learn more about to understand the code above are 1. Scope and especially hoisting 2. Objects, this and object properties and 3. Closures.

Javascript hoisting and variable assignment (with no declaration)

Looking at MDN's introduction to JavaScript, Grammar and Types section - one reads:
Declaring variables
You can declare a variable in three ways:
With the keyword var. For example, var x = 42. This syntax can be used to declare both local and global variables.
By simply assigning it a value. For example, x = 42. This always declares a global variable. It generates a strict JavaScript
warning. You shouldn't use this variant.
With the keyword let. For example, let y = 13. This syntax can be used to declare a block scope local variable. See Variable scope
below.
The following code snippet would seem to fit the "by simply assigning it a value" scenario, meaning the variable should be treated as global.
(function(){
console.log(myVar);
//the following will throw a ReferenceException error
//myVar = 10;
//the following will not, and I can understand it following the defintion of the behavior of using `var` keyword
//var myVar = 10;
})();
But running the code will generate a ReferenceException when myVar is commented, and undefined when not. I would expect it to generate undefined in both cases, since if myVar is a global variable (per definition), than javascript's variable hoisting would make it known before reaching console.log(myVar);
What is the explanation behind such behavior ? (the behavior I described is what I get when trying it in my firefox's console, but running it in jsfiddle will not throw an error).
Are self-executing functions an exception to hoisting ?
the "by simply assigning it a value" scenario
You are reading the value, not assigning it
if myVar is a global variable (per definition),
It isn't.
myVar is:
a variable scoped to the function if the function contains var myVar (or function myVar () { ... }, or it is listed as a parameter in the function definition).
a variable scoped to the block if the block contains let myVar
a global variable if a value has been assigned to it previously and neither of the above conditions are true.
Since you haven't assigned a value, it isn't a global. Since none of the above conditions are true, it isn't any kind of variable, so you get a reference error.
Regarding your comment:
I left my var when I meant var in the scenario I am trying to depict. Updated question.
… and the edit to which you refer:
Commented out code is not evaluated. Having a comment that uses the keyword var doesn't do anything.
Regarding your further edits.
You get a reference error if you try to read a variable before it has been declared.
var statements (and function declarations) are hoisted so a variable declared with those methods can be read anywhere in the function.
Assignments are not hoisted. A global variable created implicitly by assignment (which is generally not considered to be best practise and is banned in strict mode) can't be read before the value is assigned.
Since my comment seemed to help explain it to you, I will turn it into an answer:
Implicit global variable creation (when you don't actually declare it, but just assign to it) is NOT hoisted. The variable creation happens inline at the moment the assignment occurs.
Thus, when you try to read the variable, it does not exist yet and that is an error.
var or let declarations are hoisted to the top of their appropriate scope.
All of this should hopefully help explain why you should just run in strict mode where implicit global creation is illegal and not allowed and triggers an immediate error. It's basically evil. A simple typo misspelling a variable may not trigger an error when you really want it to.

why is the the function not getting called and throwing me an error?

The below is my code
function callName() {
var name="x";
function printName(){
alert(name);
}
return printName;
}
name = callName();
alert(name);
name();
When i execute it, the alert statement is printing the printName function perfectly, but the function call name() is giving an error stating string is not a function. if scope is the problem the alert should have printed the name instead of the function. I am trying to understand closures here and was trying this out and got confused with the scope management in js.
You haven't declared name in the outer scope, so it's using the global scope, and is actually pointing to window.name. Just declare it as a local variable, and you're set:
function callName() {
var name="x";
function printName(){
alert(name);
}
return printName;
}
var name = callName();
alert(name);
name();
Since window.name is the name of the window, when you assign to it, it's assigning the string contents to the name of the window, and is still a string - that's why you can't call it with name().
Note that this will only work if this code itself is within another scope - if it's on the global scope, even using var name won't help, as it will still conflict with the global window.name property.
That is because inside callName() you set the var name to string. If you do this:
var name = callName();
You will be creating a new var name different of the one inside callName().
Fiddle

Scoping Rules in JavaScript

I am going through the book JavaScript: The Complete Reference, Third Edition By: Thomas Powell; Fritz Schneider to have a detailed understanding of the concepts.
Scoping Rules
Outside of a function or object, variables are within the global space whether explicitly defined with var or not. Within a function or object, if the var statement is used, the defined variable will be local to the construct; without the statement, it will be global.
Commonly, JavaScript developers make assumptions about scoping rules with var that aren’t quite true. For example, a var statement found within a for loop does not scope that value to the loop. In this case, it is scoped to either the function it is within or to the global space if it is outside a function or an object.
Just to see what happens consequently, I coded like this,
When I press Ctrl+Space in Eclipse IDE for it to show JavaScript proposals, why am I able to access the variable jLocal outside the function?
As per the author description:
For example, a var statement found within a for loop does not scope that value to the loop. In this case, it is scoped to either the function it is within or to the global space if it is outside a function or an object.
Because at the bottom of your code you have:
...
jLocal = jLocal + j; // defined not in any functions
...
Making it global, but not necessary defined.
It isn't the case of a local function. myFunc is global, just as the variable jLocal is (albeit the name). Because of hoisting, jLocal is assumed to be declared on top of parent scope.
Looking more carefully, there's two variable's named jLocal. One local to myFunc and an implicit one on global scope.
Want a tip?
Put "use strict"; just before var global1 = true;. An HTML 5 implementation would be able to catch and show your error.

scope in javascript

i have encountered the following curious piece of code:
function foo(){
works = {hello:"world"};
function bar(){
alert('does not work');
}
var notwork = {hello:"world"};
}
foo();
alert(works.hello);
alert(notwork.hello);
Can someone please explain to me why works work, and notwork doesn't work? Or point me out to a good resource that explains this in detail.
Thank you very much!
var notwork creates a local variable valid only for the runtime of the function.
works creates a global variable that is valid throughout the javascript runtime.
var declares a variable as "local" to the function it's defined in.
Without var, you works variable is global : it can be seen/accessed/used from anywhere.
With var, your notwork variable is local to the foo function : it cannot be seen/used from outside of that function.
For more informations, you can take a look at the documentation of the var statement on MDC, which states (quoting) :
The scope of a variable is the current
function or, for variables declared
outside a function, the current
application.
Using var outside a function is
optional; assigning a value to an
undeclared variable implicitly
declares it as a global variable.
However, it is recommended to always
use var, and it is necessary within
functions in the following situations:
If a variable in a scope containing the function (including the global
scope) has the same name.
If recursive or multiple functions use variables with the same name and
intend those variables to be local.
Failure to declare the variable in
these cases will very likely lead to
unexpected results.
You've missed out the var keyword so works is being defined on the global object.
You want
var works = ...

Categories