Steve Carroll
2025-01-30 18:58:50 UTC
I've heard scope in JS described as simply as: 'Anything not inside a function'.
To that, I'd add: 'or inside of any code block'. To simplify things, I'm going
to confine this discussion of JS scope to a web browser.
Go to address 'about:blank' in your browser, now go to dev tools' Console tab
and type in: 'window' (yes, hit return). You'll see something like this:
Window {window: Window, self: Window, document: document, name: '', etc.
If you click the little drop-down triangle you'll see tons of methods
(functions) and properites (that have values, even blank ones).
Elsewhere, I pointed out that everything in JS that isn't a primitive is an
object. That blank screen you're looking at is the window object. If you type
in 'window' followed by a '.' char, you'll get an autocompletion list of things
available to the window object. OK, so what about the window object, how does
it relate to scope?
You can think of scope as the places where a variable is accessible in your
code. Run the following in a browser where you've reloaded the 'about:blank'
page (and emptied the cache, if needed):
globalVar = "I'm global" // (always hit return)
You just created a variable called "globalVar" and assigned it a value of "I'm
global"
Now type in "globalVar", you'll see the 'value' held by it on screen.
// outputs "I'm global"
Now enter this:
let globalVar = "I'm global, too!"
And type "globalVar" in like you did previously.
What came back? Where did the other one go?!
type in: window.globalVar // outputs "I'm global"
Seems the first variable, created without using a 'keyword' (such as: 'var',
'let' or 'const') somehow got 'attached' to the windown object (JS created it
using the 'var' keyword even though you didn't use it!).
What is the one that used the 'let' keyword 'attached' to?
You may have heard that the window object is the global object in a browser,
yet, using 'let' would seemingly appear *more* global as it can be directly
accessed, as opposed to: 'window.globalVar'. What's going on?
Don't let the browser's pecularlity here confuse you. The thing we're looking
for is: What's at the top of the food chain in the JS we write or encounter?
What is 'not inside a function or block of code'? What does that even mean?
Let's define a var inside of a function. Reload your page again and enter this
function, which contiains a 'code block' (meaning: code wrapped in curly
braces... but NOT as used in JS objects!)
function scopeAdope(){
let myVar = "What's my scope?"
console.log(myVar)
}
Run it: scopeAdope() // outputs "What's my scope?"
Now type the name of the var, "myVar", to attempt to 'access' it like you did
earlier: "Uncaught ReferenceError: myVar is not defined" - Yikes!
It's 'scope' is limited to the code block in the function. Now try this:
let yourVar = "I have a broader scope!"
function scopeAdope2(){
let myVar = "What's my scope?"
console.log(myVar)
console.log(yourVar)
}
Run it: scopeAdope2() // outputs both vars
Notice that the function has 'access' to 'yourVar' even though it was defined
outside of the function. The topic of scope can get confusing as more code is
added (i.e. functions within functions) but on a basic level, this is the
general idea.
Let's take a 'scope break' and create our own object in the browser window:
let myDiv = document.createElement('div') // creates an empty, div tag (element)
Want to see all the things 'attached' to what you just created?
console.dir(myDiv)
Click the drop-down widget if needed. Looking in the list you can see a
proptery named: 'textContent'
Do this:
myDiv.textContent = "I'm the new div!"
Now type: myDiv // outputs "I'm the new div!"
But it's not on the screen! That's right, it's not been added to the DOM yet.
To do that you need a reference to the body tag, where all displayed content
should live. Do this:
let body = document.querySelector('body')
Why not use createElement() for this, like we did earlier? Look in your dev
tools Elements tab, you'll see 'body' (and other elements) already exist. All
you need is a way to reference 'body' and if you did what I just told you to
do, you now have it. All you need is to 'append' 'myDiv' to the 'body'. Back to
the console tab:
body.append(myDiv) // you'll see what this does
myDiv.style.color = 'red' // I suspect you can guess what that does...
myDiv.style.fontSize = '2em' // ...and what that does
Handy tip: things like 'font-size', as seen in CSS, become 'fontSize' in JS.
Bonus question: Is 'myDiv' attached to the window obj (or the document obj)?
--
Reference page:
<vmekhl$74sp$***@fretwizzer.eternal-september.org>
Setup:
<vmgi9e$u5m6$***@fretwizzer.eternal-september.org>
Variables:
<vmh41h$u5m6$***@fretwizzer.eternal-september.org>
Functions:
<vmh7ln$u5m6$***@fretwizzer.eternal-september.org>
Arrays/looping:
<vmmi7n$3edp3$***@fretwizzer.eternal-september.org>
Object Basics:
<vne73j$2i8m1$***@dont-email.me>
Calculator project - Part 1
<vmjd3a$2bdqi$***@fretwizzer.eternal-september.org>
Calculator project - Part 2
<vmrch2$14j7l$***@fretwizzer.eternal-september.org>
DOM - Part 1
<vmubfb$1pvlc$***@fretwizzer.eternal-september.org>
Text generator project - Part 1
<vmug55$1pvlc$***@fretwizzer.eternal-september.org>
Text generator project - Part 2
<vn66pb$36go$***@fretwizzer.eternal-september.org>
Text generator project - Part 3
<vn69if$56c0$***@fretwizzer.eternal-september.org>
Programming vs Code
<vn8vtp$192cl$***@fretwizzer.eternal-september.org>
To that, I'd add: 'or inside of any code block'. To simplify things, I'm going
to confine this discussion of JS scope to a web browser.
Go to address 'about:blank' in your browser, now go to dev tools' Console tab
and type in: 'window' (yes, hit return). You'll see something like this:
Window {window: Window, self: Window, document: document, name: '', etc.
If you click the little drop-down triangle you'll see tons of methods
(functions) and properites (that have values, even blank ones).
Elsewhere, I pointed out that everything in JS that isn't a primitive is an
object. That blank screen you're looking at is the window object. If you type
in 'window' followed by a '.' char, you'll get an autocompletion list of things
available to the window object. OK, so what about the window object, how does
it relate to scope?
You can think of scope as the places where a variable is accessible in your
code. Run the following in a browser where you've reloaded the 'about:blank'
page (and emptied the cache, if needed):
globalVar = "I'm global" // (always hit return)
You just created a variable called "globalVar" and assigned it a value of "I'm
global"
Now type in "globalVar", you'll see the 'value' held by it on screen.
// outputs "I'm global"
Now enter this:
let globalVar = "I'm global, too!"
And type "globalVar" in like you did previously.
What came back? Where did the other one go?!
type in: window.globalVar // outputs "I'm global"
Seems the first variable, created without using a 'keyword' (such as: 'var',
'let' or 'const') somehow got 'attached' to the windown object (JS created it
using the 'var' keyword even though you didn't use it!).
What is the one that used the 'let' keyword 'attached' to?
You may have heard that the window object is the global object in a browser,
yet, using 'let' would seemingly appear *more* global as it can be directly
accessed, as opposed to: 'window.globalVar'. What's going on?
Don't let the browser's pecularlity here confuse you. The thing we're looking
for is: What's at the top of the food chain in the JS we write or encounter?
What is 'not inside a function or block of code'? What does that even mean?
Let's define a var inside of a function. Reload your page again and enter this
function, which contiains a 'code block' (meaning: code wrapped in curly
braces... but NOT as used in JS objects!)
function scopeAdope(){
let myVar = "What's my scope?"
console.log(myVar)
}
Run it: scopeAdope() // outputs "What's my scope?"
Now type the name of the var, "myVar", to attempt to 'access' it like you did
earlier: "Uncaught ReferenceError: myVar is not defined" - Yikes!
It's 'scope' is limited to the code block in the function. Now try this:
let yourVar = "I have a broader scope!"
function scopeAdope2(){
let myVar = "What's my scope?"
console.log(myVar)
console.log(yourVar)
}
Run it: scopeAdope2() // outputs both vars
Notice that the function has 'access' to 'yourVar' even though it was defined
outside of the function. The topic of scope can get confusing as more code is
added (i.e. functions within functions) but on a basic level, this is the
general idea.
Let's take a 'scope break' and create our own object in the browser window:
let myDiv = document.createElement('div') // creates an empty, div tag (element)
Want to see all the things 'attached' to what you just created?
console.dir(myDiv)
Click the drop-down widget if needed. Looking in the list you can see a
proptery named: 'textContent'
Do this:
myDiv.textContent = "I'm the new div!"
Now type: myDiv // outputs "I'm the new div!"
But it's not on the screen! That's right, it's not been added to the DOM yet.
To do that you need a reference to the body tag, where all displayed content
should live. Do this:
let body = document.querySelector('body')
Why not use createElement() for this, like we did earlier? Look in your dev
tools Elements tab, you'll see 'body' (and other elements) already exist. All
you need is a way to reference 'body' and if you did what I just told you to
do, you now have it. All you need is to 'append' 'myDiv' to the 'body'. Back to
the console tab:
body.append(myDiv) // you'll see what this does
myDiv.style.color = 'red' // I suspect you can guess what that does...
myDiv.style.fontSize = '2em' // ...and what that does
Handy tip: things like 'font-size', as seen in CSS, become 'fontSize' in JS.
Bonus question: Is 'myDiv' attached to the window obj (or the document obj)?
--
Reference page:
<vmekhl$74sp$***@fretwizzer.eternal-september.org>
Setup:
<vmgi9e$u5m6$***@fretwizzer.eternal-september.org>
Variables:
<vmh41h$u5m6$***@fretwizzer.eternal-september.org>
Functions:
<vmh7ln$u5m6$***@fretwizzer.eternal-september.org>
Arrays/looping:
<vmmi7n$3edp3$***@fretwizzer.eternal-september.org>
Object Basics:
<vne73j$2i8m1$***@dont-email.me>
Calculator project - Part 1
<vmjd3a$2bdqi$***@fretwizzer.eternal-september.org>
Calculator project - Part 2
<vmrch2$14j7l$***@fretwizzer.eternal-september.org>
DOM - Part 1
<vmubfb$1pvlc$***@fretwizzer.eternal-september.org>
Text generator project - Part 1
<vmug55$1pvlc$***@fretwizzer.eternal-september.org>
Text generator project - Part 2
<vn66pb$36go$***@fretwizzer.eternal-september.org>
Text generator project - Part 3
<vn69if$56c0$***@fretwizzer.eternal-september.org>
Programming vs Code
<vn8vtp$192cl$***@fretwizzer.eternal-september.org>