-
Notifications
You must be signed in to change notification settings - Fork 480
Added to the scope JS 101 article #201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
fb9ee66
b9ebfc6
0ce4fb3
a029a3b
0ba297d
ba32ebb
1d28c53
ce975df
21900b5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,90 @@ | ||
--- | ||
title: Scope | ||
level: beginner | ||
source: http://jqfundamentals.com/legacy | ||
attribution: | ||
title: Scope | ||
level: beginner | ||
source: http://jqfundamentals.com/legacy, http://javascriptplayground.com/blog/2012/04/javascript-variable-scope-this | ||
attribution: | ||
- jQuery Fundamentals | ||
--- | ||
|
||
"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. | ||
"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 & are executed in. | ||
|
||
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 to the declared variable. | ||
|
||
There are two types of scopes in JavaScript: Global and local. Lets talk about each of them in turn. | ||
|
||
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. A variable that is defined from anywhere but within a function is global. | ||
|
||
``` | ||
var x = 9; | ||
``` | ||
|
||
Once that variable is set, it exists on the global object. 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`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Better: If this variable declaration occurs outside of a function, then the variable |
||
|
||
The only other scope we can have is __Local Scope__. JavaScript scopes at a function level. For example: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Better: JavaScript also creates a Local Scope inside each function body. For exampmle: |
||
|
||
``` | ||
function myFunc() { | ||
var x = 5; | ||
}; | ||
console.log(x); // ReferenceError: x is not defined | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
``` | ||
|
||
Since `x` was initialised within `myFunc`, it is only accessible within `myFunc`, and we get a reference error if we try to access it outside of `myFunc`. | ||
|
||
__A word of Caution__ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this be a header or a note, rather than just an italicized fragment? |
||
|
||
If you declare a variable & forget to use the `var` keyword, that variable is automically made global. So this code would work: | ||
|
||
``` | ||
function myFunc() { | ||
x = 5; | ||
}); | ||
console.log(x); // 5 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Inner spacing: |
||
``` | ||
|
||
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. | ||
|
||
Secondly, it's considered bad practise to clutter the global scope. You should add as fewer properties as you possibly can to the global object, and try to keep your program contained within its own scope. That's why you'll see libaries such as jQuery often do this: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems like a restatement of the first reason not to have global variables. I'm hesitant to just say a thing is a bad practice without saying why it's a bad practice, but in fact you've already said why it's a bad practice, so this paragraph seems redundant to me. I'd simply point out that IIFEs provide a way to avoid polluting the global scope -- ensuring that variables can't be tampered with by other code -- and move on to the example below. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. practise -> practice There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @rmurphey do you mean to remove the entire jQuery IIFE example, or just reword the line that starts "Secondly..." to mention IIFEs, then show the jQuery example, and then move onto the next example (which starts on line 59) ? |
||
|
||
``` | ||
(function() { | ||
var jQuery = { /* all my methods go here */ }; | ||
window.jQuery = jQuery. | ||
})(); | ||
``` | ||
|
||
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_. | ||
|
||
Because local scope works through functions, any functions defined within another have access to variables defined in the outer function: | ||
|
||
``` | ||
function outer() { | ||
var x = 5; | ||
function inner() { | ||
console.log(x); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again - |
||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This example makes more sense if the |
||
|
||
inner(); // logs 5 | ||
} | ||
``` | ||
|
||
But the `outer()` function doesn't have access to any variables declared within `inner()`: | ||
|
||
``` | ||
function outer() { | ||
var x = 5; | ||
|
||
function inner() { | ||
console.log(x); | ||
var y = 10; | ||
} | ||
|
||
inner(); // logs 5 | ||
|
||
console.log(y); // ReferenceError: y is not defined | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This and also 6 lines before it, need spacing inside the function args: |
||
} | ||
``` | ||
|
||
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. | ||
|
||
``` | ||
|
@@ -22,9 +97,9 @@ var sayHello = function() { | |
|
||
}; | ||
|
||
sayHello(); // logs "hello" | ||
sayHello(); // "hello" | ||
|
||
console.log( foo ); // also logs "hello" | ||
console.log( foo ); // "hello" | ||
``` | ||
|
||
``` | ||
|
@@ -37,9 +112,9 @@ var sayHello = function() { | |
|
||
}; | ||
|
||
sayHello(); // logs "hello" | ||
sayHello(); // "hello" | ||
|
||
console.log( foo ); // doesn"t log anything | ||
console.log( foo ); // undefined | ||
``` | ||
|
||
``` | ||
|
@@ -54,9 +129,9 @@ var sayHello = function() { | |
|
||
}; | ||
|
||
sayHello(); // logs "hello" | ||
sayHello(); // "hello" | ||
|
||
console.log( foo ); // logs "world" | ||
console.log( foo ); // "world" | ||
``` | ||
|
||
``` | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this accurate? Seems the jqf content has been largely replaced.