Skip to content

Commit 6fc9783

Browse files
jackfranklinajpiano
authored andcommitted
Expand the JavaScript 101 'Scope' article with more useful information and explanations. Fixes #201.
1 parent 84ee4cf commit 6fc9783

File tree

1 file changed

+115
-36
lines changed

1 file changed

+115
-36
lines changed

page/javascript-101/scope.md

Lines changed: 115 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,123 @@
11
---
2-
title: Scope
3-
level: beginner
4-
source: http://jqfundamentals.com/legacy
5-
attribution:
2+
title: Scope
3+
level: beginner
4+
source: http://jqfundamentals.com/legacy, http://javascriptplayground.com/blog/2012/04/javascript-variable-scope-this
5+
attribution:
66
- jQuery Fundamentals
77
---
88

9-
"Scope" refers to the variables that are available to a piece of code at a given time. A lack of understanding of scope can lead to frustrating debugging experiences.
9+
"Scope" refers to the variables that are available to a piece of code at a given time. A lack of understanding of scope can lead to frustrating debugging experiences. The idea of "scope" is that it's where certain functions or variables are accessible from in our code, and the context in which they exist and are executed in.
1010

11-
When a variable is declared inside of a function using the `var` keyword, it is only available to code inside of that function — code outside of that function cannot access the variable. On the other hand, functions defined inside that function will have access to the declared variable.
11+
There are two types of scopes in JavaScript: Global and local. Lets talk about each of them in turn.
1212

13-
Furthermore, variables that are declared inside a function without the `var` keyword are not local to the function — JavaScript will traverse the scope chain all the way up to the window scope to find where the variable was previously defined. If the variable wasn't previously defined, it will be defined in the global scope, which can have unexpected consequences.
13+
## Global Scope
14+
15+
The first scope is __Global Scope__. This is very easy to define. If a variable or function is _global_, it can be accessed from anywhere within a program. In a browser, the global scope is the `window` object. If a variable declaration occurs outside of a function, then that variable exists on the global object. For example:
1416

1517
```
16-
// Functions have access to variables defined in the same scope
17-
var foo = "hello";
18-
var sayHello = function() {
19-
console.log( foo );
18+
var x = 9;
19+
```
20+
21+
Once that variable had been defined, it could be referenced as `window.x`, but because it exists on the global object we can simply refer to it as `x`.
22+
23+
## Local Scope
24+
JavaScript also creates a __Local Scope__ inside each function body. For example:
25+
26+
```
27+
function myFunc() {
28+
var x = 5;
2029
};
30+
console.log( x ); // ReferenceError: x is not defined
31+
```
32+
33+
Since `x` was initialized within `myFunc()`, it is only accessible within `myFunc()`, and we get a reference error if we try to access it outside of `myFunc()`.
34+
35+
##A word of Caution
36+
37+
If you declare a variable and forget to use the `var` keyword, that variable is automically made global. So this code would work:
38+
39+
```
40+
function myFunc() {
41+
x = 5;
42+
});
43+
console.log( x ); // 5
44+
```
45+
46+
This is a bad idea. Any variable that is global can have its value changed by any other parts of a program or any other script. This is undesirable, as it could lead to unforseen side effects.
47+
48+
Secondly, Immediately-Invoked Funcion Expressions provide a way to avoid global variables. You'll see many libraries such as jQuery often use these:
49+
50+
```
51+
(function() {
52+
var jQuery = { /* all my methods go here */ };
53+
window.jQuery = jQuery.
54+
})();
55+
```
56+
57+
Wrapping everything in a function which is then immediately invoked means all the variables within that function are bound to the _local scope_. At the very end you can then expose all your methods by binding the `jQuery` object to the `window`, the _global object_. To read more about Immediatly-Invoked Functions, check out Ben Alman's [Immediately-Invoked Function Expression](http://benalman.com/news/2010/11/immediately-invoked-function-expression/) article.
58+
59+
Because local scope works through functions, any functions defined within another have access to variables defined in the outer function:
60+
61+
```
62+
function outer() {
63+
var x = 5;
64+
function inner() {
65+
console.log( x );
66+
}
67+
68+
inner(); // 5
69+
}
70+
```
71+
72+
But the `outer()` function doesn't have access to any variables declared within `inner()`:
73+
74+
```
75+
function outer() {
76+
var x = 5;
2177
22-
sayHello(); // "hello"
23-
console.log( foo ); // "hello"
78+
function inner() {
79+
console.log( x );
80+
var y = 10;
81+
}
82+
83+
inner(); // 5
84+
85+
console.log( y ); // ReferenceError: y is not defined
86+
}
2487
```
2588

89+
Furthermore, variables that are declared inside a function without the `var` keyword are not local to the function — JavaScript will traverse the scope chain all the way up to the window scope to find where the variable was previously defined. If the variable wasn't previously defined, it will be defined in the global scope, which can have unexpected consequences.
90+
2691
```
27-
// Code outside the scope in which a variable was defined does not have access to the variable
92+
// Functions have access to variables defined in the same scope
93+
var foo = "hello";
94+
2895
var sayHello = function() {
29-
var foo = "hello";
3096
console.log( foo );
3197
};
3298
33-
sayHello(); // hello
99+
sayHello(); // "hello"
34100
35-
console.log( foo ); // undefined
101+
console.log( foo ); // "hello"
36102
```
37103

104+
Variables with the same name can exist in different scopes with different values:
38105
```
39-
// Variables with the same name can exist in different scopes with different values
40106
var foo = "world";
41107
42108
var sayHello = function() {
43109
var foo = "hello";
44110
console.log( foo );
45111
};
46112
47-
sayHello(); // logs "hello"
48-
console.log( foo ); // logs "world"
113+
sayHello(); // "hello"
114+
115+
console.log( foo ); // "world"
49116
```
50117

118+
When you reference a global variable within a function, that function can see changes to the variable value after the function is defined.
119+
51120
```
52-
// Functions can see changes in variable values after the function is defined
53121
var myFunction = function() {
54122
var foo = "hello";
55123
var myFn = function() {
@@ -63,32 +131,43 @@ var f = myFunction();
63131
f(); // "world"
64132
```
65133

134+
Here's a more complex example of scopes at play:
135+
66136
```
67-
// Scope insanity
68-
// a self-executing anonymous function
69137
(function() {
70138
var baz = 1;
139+
71140
var bim = function() {
72-
alert( baz );
141+
console.log( baz );
142+
};
143+
144+
bar = function() {
145+
console.log( baz );
73146
};
74147
75148
bar = function() {
76-
alert( baz );
149+
console.log( baz );
77150
};
78151
79152
})();
153+
```
154+
In this instance, running:
155+
156+
```
157+
console.log( baz ); // baz is not defined outside of the function
158+
```
159+
160+
Gives us a `ReferenceError`. `baz` was only defined within the function, and was never exposed to the global scope.
80161

81-
// baz is not defined outside of the function
82-
console.log( baz );
162+
```
163+
bar(); // 1
164+
```
83165

84-
// bar is defined outside of the anonymous function
85-
// because it wasn't declared with var; furthermore,
86-
// because it was defined in the same scope as baz,
87-
// it has access to baz even though other code
88-
// outside of the function does not
89-
bar();
166+
`bar()` may have been defined within the anonymous function, but it was defined without the `var` keyword, which means it wasn't bound to the local scope and was instead created globally. Furthermore, it has access to the `baz` variable because `bar()` was defined within the same scope as `baz`. This means it has access to it, even though other code outside of the function does not.
90167

91-
// bim is not defined outside of the anonymous function,
92-
// so this will result in an error
93-
bim();
168+
169+
```
170+
bim(); // ReferenceError: bim is not defined
94171
```
172+
173+
`bim()` was only defined within the function, so does not exist on the global object as it was defined locally.

0 commit comments

Comments
 (0)