28
loading...
This website collects cookies to deliver better user experience
Any reference to a variable that's initially undeclared is left as an uncolored marble during that file's compilation; this color cannot be determined until other relevant files have been compiled and the application runtime commences. That deferred lookup will eventually resolve the color to whichever scope the variable is found in (likely the global scope).
var studentName = "Suzy";
function printStudent(studentName) {
studentName = studentName.toUpperCase();
console.log(studentName);
}
printStudent("Frank");
// FRANK
printStudent(studentName);
// SUZY
console.log(studentName);
// Suzy
studentName
declaration on line 1, creates a new variable in the global scope. studentName
references in the printStudent
function refer to a different local scoped variable and not the global scoped studentName
variable. This behavior is called Shadowing.var
and function
declarations also expose themselves as properties (of the same name as the identifier) on the global object—essentially an object representation of the global scope. Consider the program:
var studentName = "Suzy";
function printStudent(studentName) {
console.log(studentName);
console.log(window.studentName);
}
printStudent("Frank");
// "Frank"
// "Suzy"
window.variableName
we can still access the globally scoped shadowed variable in a function.window.studentName
is a mirror of the global studentName
variable, not a separate snapshot copy. Changes to one are still seen from the other, in either direction.var
or function
.var special = 42;
function lookingFor(special) {
var another = {
special: special,
};
function keepLooking() {
var special = 3.141592;
console.log(special);
console.log(another.special); // Ooo, tricky!
console.log(window.special);
}
keepLooking();
}
lookingFor(112358132134);
// 3.141592
// 112358132134
// 42
special
variable passed as a parameter to the lookingFor
function in the keepLooking
function. Does that mean we accessed a shadowed variable?
special: special
is copying the value of the special
parameter variable into another container (a property of the same name). This doesn't mean that we are accessing the parameter special
. It means we are accessing the copy of the value it had at that moment, by way of another container. We cannot reassign the special
parameter to a different value from the inside keepLooking
function.special
parameter.let
can shadow var
, but var
can't shadow let
. Consider the example:
function something() {
var special = "JavaScript";
{
let special = 42; // totally fine shadowing
// ..
}
}
function another() {
// ..
{
let special = "JavaScript";
{
var special = 42;
// ^^^ Syntax Error
// ..
}
}
}
another()
function, the inner var special
declaration is attempting to declare a function-wide special
, which in and of itself is fine (as shown by the something()
function).special
has already been defined.SyntaxError
is because the var
is basically trying to "cross the boundary" of (or hop over) the let
declaration of the same name, which is not allowed.function another() {
// ..
{
let special = "JavaScript";
ajax("https://some.url", function callback() {
// totally fine shadowing
var special = "JavaScript";
// ..
});
}
}
function askQuestion() {
// ..
}
var askQuestion = function(){
//..
};
var askQuestion = function ofTheTeacher() {
// ..
};
askQuestion
can be accessed in the outer scope, but what about ofTheTeacher
identifier? ofTheTeacher
is declared as an identifier inside the function itself:
var askQuestion = function ofTheTeacher() {
console.log(ofTheTeacher);
};
askQuestion();
// function ofTheTeacher()...
console.log(ofTheTeacher);
// ReferenceError: ofTheTeacher is not defined
var askQuestion = () => {
// ..
};
function
to define it.