Section 2: Base Syntax & Features - Diving Right Into JavaScript
The goals
๐ช๐ปDive into Core Syntax
โ๐ปUnderstand Variables & Data Types
๐๐ปWork with Operators
๐๐ปExplore & Use Functions
Variables & Constants
Var
Before the advent of ES6, var declarations ruled. There are issues associated with variables declared with var, though. That is why it was necessary for new ways to declare variables to emerge. First, let's get to understand var more before we discuss those issues.
Scope of var
Scope essentially means where these variables are available for use. var declarations are globally scoped or function/locally scoped.
The scope is global when a var variable is declared outside a function. This means that any variable that is declared with var outside a function block is available for use in the whole window.
var is function scoped when it is declared within a function. This means that it is available and can be accessed only within that function.
To understand further, look at the example below.
var greeter = "hey hi";
function newFunction() {
var hello = "hello";
}
Here, greeter is globally scoped because it exists outside a function while hello is function scoped. So we cannot access the variable hello outside of a function. So if we do this:
var tester = "hey hi";
function newFunction() {
var hello = "hello";
}
console.log(hello); // error: hello is not defined
We'll get an error which is as a result of hello not being available outside the function.
var variables can be re-declared and updated
This means that we can do this within the same scope and won't get an error.
var greeter = "hey hi";
var greeter = "say Hello instead";
and this also
var greeter = "hey hi";
greeter = "say Hello instead";
Hoisting of var
Hoisting is a JavaScript mechanism where variables and function declarations are moved to the top of their scope before code execution. This means that if we do this:
console.log (greeter);
var greeter = "say hello"
it is interpreted as this:
var greeter;
console.log(greeter); // greeter is undefined
greeter = "say hello"
So var variables are hoisted to the top of their scope and initialized with a value of undefined.
Problem with var
There's a weakness that comes with var. I'll use the example below to explain:
var greeter = "hey hi";
var times = 4;
if (times > 3) {
var greeter = "say Hello instead";
}
console.log(greeter) // "say Hello instead"
So, since times > 3 returns true, greeter is redefined to "say Hello instead". While this is not a problem if you knowingly want greeter to be redefined, it becomes a problem when you do not realize that a variable greeter has already been defined before.
If you have used greeter in other parts of your code, you might be surprised at the output you might get. This will likely cause a lot of bugs in your code. This is why let and const are necessary.
Let
let is now preferred for variable declaration. It's no surprise as it comes as an improvement to var declarations. It also solves the problem with var that we just covered. Let's consider why this is so.
let is block scoped
A block is a chunk of code bounded by {}. A block lives in curly braces. Anything within curly braces is a block.
So a variable declared in a block with let is only available for use within that block. Let me explain this with an example:
let greeting = "say Hi";
let times = 4;
if (times > 3) {
let hello = "say Hello instead";
console.log(hello);// "say Hello instead"
}
console.log(hello) // hello is not defined
We see that using hello outside its block (the curly braces where it was defined) returns an error. This is because let variables are block scoped .
let can be updated but not re-declared.
Just like var, a variable declared with let can be updated within its scope. Unlike var, a let variable cannot be re-declared within its scope. So while this will work:
let greeting = "say Hi";
greeting = "say Hello instead";
this will return an error:
let greeting = "say Hi";
let greeting = "say Hello instead"; // error: Identifier 'greeting' has already been declared
However, if the same variable is defined in different scopes, there will be no error:
let greeting = "say Hi";
if (true) {
let greeting = "say Hello instead";
console.log(greeting); // "say Hello instead"
}
console.log(greeting); // "say Hi"
Why is there no error? This is because both instances are treated as different variables since they have different scopes.
This fact makes let a better choice than var. When using let, you don't have to bother if you have used a name for a variable before as a variable exists only within its scope.
Also, since a variable cannot be declared more than once within a scope, then the problem discussed earlier that occurs with var does not happen.
Hoisting of let
Just like var, let declarations are hoisted to the top. Unlike var which is initialized as undefined, the let keyword is not initialized. So if you try to use a let variable before declaration, you'll get a Reference Error.
Const
Variables declared with the const maintain constant values. const declarations share some similarities with let declarations.
const declarations are block scoped
Like let declarations, const declarations can only be accessed within the block they were declared.
const cannot be updated or re-declared
This means that the value of a variable declared with const remains the same within its scope. It cannot be updated or re-declared. So if we declare a variable with const, we can neither do this:
const greeting = "say Hi";
greeting = "say Hello instead";// error: Assignment to constant variable.
nor this:
const greeting = "say Hi";
const greeting = "say Hello instead";// error: Identifier 'greeting' has already been declared
Every const declaration, therefore, must be initialized at the time of declaration.
This behavior is somehow different when it comes to objects declared with const. While a const object cannot be updated, the properties of this objects can be updated. Therefore, if we declare a const object as this:
const greeting = {
message: "say Hi",
times: 4
}
while we cannot do this:
greeting = {
words: "Hello",
number: "five"
} // error: Assignment to constant variable.
we can do this:
greeting.message = "say Hello instead";
This will update the value of greeting.message without returning errors.
Hoisting of const
Just like let, const declarations are hoisted to the top but are not initialized.
So just in case you missed the differences, here they are:
- var declarations are globally scoped or function scoped while let and const are block scoped.
- var variables can be updated and re-declared within its scope; let variables can be updated but not re-declared; const variables can neither be updated nor re-declared.
- They are all hoisted to the top of their scope. But while var variables are initialized with undefined, let and const variables are not initialized.
- While var and let can be declared without being initialized, const must be initialized during declaration.
Variable Naming
Allowed
let username;
-> Best Practice: camelCase
let ageGroup5;
-> only letters and digits
let $kindOfSpecial;
-> Starting with $ is allowed
let _internalValue;
-> Starting with _ is allowed
Not Allowed / Not Recommended
let user_name;
-> Allowed but bad practice
let 21Players;
-> Starting digits not allowed
let user-b;
-> No special characters!
let let;
-> Keywords not allowed
Operators
Mathmatical
+: Add two numbers
-: Subtract two numbers
x: Multiply two numbers
/ : Divide two numbers
%: Divide two numbers, yield remainder
**: Exponentiation (e.g. 2**3 = 8)
=: Assign value to variable
+=, -=, ... : Perform calculation and re-assign result to variable
++, --: Increment / Decrement variable value + re-assign
Template Literals
Template literals are literals delimited with backtick (`) characters, allowing for multi-line strings, string interpolation with embedded expressions, and special constructs called tagged templates.
Template literals are sometimes informally called template strings, because they are used most commonly for string interpolation (to create strings by doing substitution of placeholders). However, a tagged template literal may not result in a string; it can be used with a custom tag function to perform whatever operations you want on the different parts of the template literal.
Syntax
`string text`
`string text line 1
string text line 2`
`string text ${expression} string text`
tagFunction`string text ${expression} string text`
JavaScript Variable Scope
Scope determines the accessibility (visibility) of variables.
JavaScript has 3 types of scope:
- Block scope
- Function scope
- Global scope
Block Scope
Before ES6 (2015), JavaScript had only Global Scope and Function Scope.
ES6 introduced two important new JavaScript keywords: let and const.
These two keywords provide Block Scope in JavaScript.
Variables declared inside a { } block cannot be accessed from outside the block:
Example
{
let x = 2;
}
// x can NOT be used here
Variables declared with the var keyword can NOT have block scope.
Variables declared inside a { } block can be accessed from outside the block.
Example
{
var x = 2;
}
// x CAN be used here
Local Scope
Variables declared within a JavaScript function, become LOCAL to the function.
Example
// code here can NOT use carName
function myFunction() {
let carName = "Volvo";
// code here CAN use carName
}
// code here can NOT use carName
Since local variables are only recognized inside their functions, variables with the same name can be used in different functions.
Local variables are created when a function starts, and deleted when the function is completed.
Function Scope
JavaScript has function scope: Each function creates a new scope.
Variables defined inside a function are not accessible (visible) from outside the function.
Variables declared with var, let and const are quite similar when declared inside a function.
They all have Function Scope:
function myFunction() {
var carName = "Volvo"; // Function Scope
}
function myFunction() {
let carName = "Volvo"; // Function Scope
}
๋ก์ปฌ("ํจ์ ๋ด๋ถ") ๋ณ์์ ์ ์ญ ๋ณ์์ ๋ํด ๋ฐฐ์ ์ต๋๋ค.
๋ค์์ ์ฝ๋๋ฅผ ์คํํ๋ฉด ์ด๋ป๊ฒ ๋ ๊น์?
let userName = 'Max';
function greetUser(name) {
let userName = name;
alert(userName);
}
userName = 'Manu';
greetUser('Max');
์ฌ์ค ์ด ์ฝ๋๋ฅผ ์คํํ๋ฉด 'Max'('Manu'๊ฐ ์๋)๋ผ๋ ๊ฒฝ๊ณ ๊ฐ ํ์๋ ๊ฒ๋๋ค.
userName์ ๋ ๋ฒ ์ด์ ์ฌ์ฉํ๊ณ ์ ์ธํด์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฒ์ด๋ผ ์๊ฐํ์ จ์ ์๋ ์์ต๋๋ค - ๊ทธ๋ฆฌ๊ณ ๋ฐฐ์ฐ์ ๋ฐ์ ๊ฐ์ด, ์ด๋ ํ์ฉ๋์ง ์์ฃ .
์ด๋ ์ค์ ๋ก ๋์ผํ ์์ค/๋์ผํ ๋ฒ์์์๋ ํ์ฉ๋์ง ์์ต๋๋ค.
๋ค์์ ์ฝ๋๋ ์๋ํ์ง ์์ ๊ฒ๋๋ค.
let userName = 'Max';
let userName = 'Manu';
์ ์ฒ์ ์ฝ๋ ์ค๋ํซ์ ์๋์ ํ์๊น์?
์๋์ ์ฝ๋๋ก
๋จผ์ ์ ์ญ ๋ณ์ userName์ ์์ฑํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
let userName = 'Max';
๊ทธ๋ฌ๋ ๊ทธ๋ฐ ๋ค์์๋, ์ ์ญ ์์ค์์๋ ์ด๋ฅผ ๋ค์ ์ ์ธํ์ง ์์ต๋๋ค(ํ์ฉ๋์ง ์์).
ํจ์ ๋ด์์๋ง ๋ค๋ฅธ ๋ณ์๋ฅผ ์ ์ธํ์ฃ . ๊ทธ๋ฌ๋ ํจ์์ ๋ณ์๋ ์์ฒด ๋ฒ์๋ฅผ ๊ฐ๊ธฐ ๋๋ฌธ์ JavaScript๋ "์๋์"์ด๋ผ๋ ์์ ์ ์ํํฉ๋๋ค.
์ด ์์ ์ ๋ค๋ฅธ ๋ฒ์์ ์ ๋ณ์๋ฅผ ์์ฑํฉ๋๋ค - ์ด๋ฐ ๋ณ์๋ ์ ์ญ ๋ณ์๋ฅผ ๋ฎ์ด์ฐ๊ฑฐ๋ ์ ๊ฑฐํ์ง ์์ต๋๋ค - ๋์ ๊ณต์กดํ์ฃ .
๊ทธ๋ฌ๋ฉด greetUser ํจ์ ๋ด์์ userName์ ์ฐธ์กฐํ ๋ ํญ์ ๋ก์ปฌ ์๋์ฐ ๋ณ์๋ฅผ ์ฐธ์กฐํฉ๋๋ค. JavaScript๋ ํด๋น ์ง์ญ ๋ณ์๊ฐ ์กด์ฌํ์ง ์๋ ๊ฒฝ์ฐ์๋ง ์ ์ญ ๋ณ์๋ก ํด๋ฐฑํฉ๋๋ค.
ํจ์๋ฅผ ์คํํ๋ ๋ฐ์ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋ ๊ฒ์ผ๋ก ๋ณด์ฌ ํผ๋์ค๋ฌ์ฐ์ค ์ ์์ต๋๋ค.
- function add() {
- something = someNum + someOtherNum;
- }
add() vs add
์ ์ด๋ฌํ "๋ ๊ฐ์ง ๋ฐฉ๋ฒ"์ด ์๋์ง๋ฅผ ์ดํดํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค!
๋ณดํต, ์ด๋ฆ์ผ๋ก ์ ์๋ ํจ์(์: add)๋ฅผ ํธ์ถํ ๋ ๊ดํธ๋ฅผ ์ถ๊ฐํฉ๋๋ค. (ํจ์๊ฐ ํ์ํ ๋ชจ๋ ๋งค๊ฐ๋ณ์๊ฐ ๊ดํธ ์์ ๋ค์ด๊ฐ๊ฑฐ๋ ์์ ์์์ฒ๋ผ ๋งค๊ฐ๋ณ์๊ฐ ํ์ํ์ง ์์ ๊ฒฝ์ฐ ๋น ๊ดํธ๋ฅผ ์ถ๊ฐํฉ๋๋ค).
=> add()
์ด๊ฒ ๋ฐ๋ก ์ฝ๋์ ํจ์๋ฅผ ์คํํ๋ ๋ฐฉ๋ฒ์ ๋๋ค. JavaScript๋ ์ด ๋ฌธ์ฅ์ด ๋์ฌ ๋๋ง๋ค ํจ์์ ์ฝ๋๋ฅผ ์คํํฉ๋๋ค. ์ด์์ ๋๋ค!
ํ์ง๋ง ๊ฐ๋์, ํจ์๋ฅผ ๋ฐ๋ก ์คํํ๊ณ ์ถ์ง ์์ ๋๊ฐ ์์ต๋๋ค. JavaScript์ ๋ฏธ๋์ ์ด๋ ์์ ์(์: ์ผ๋ถ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ๋) ์ด๋ค ๊ธฐ๋ฅ์ด ์คํ๋๊ธธ ์ํ ์๋ ์์ต๋๋ค.
์ด ๊ฒฝ์ฐ์ ํจ์๋ฅผ ์ง์ ํธ์ถํ๋ ๋์ JavaScript์ ํจ์ ์ด๋ฆ์ ์ ๊ณตํฉ๋๋ค.
=> someButton.addEventListener('click', add);
์ด ์ค๋ํซ์ JavaScript์๊ฒ ์ด๋ ๊ฒ ์ง์ํฉ๋๋ค. "์ด ๋ฒํผ์ด ํด๋ฆญ๋๋ฉด add๋ฅผ ์คํํด.".
someButton.addEventListener('click', add()); ๋ ์ด ๊ฒฝ์ฐ์๋ ์ค๋ต์ด ๋ ๊ฒ๋๋ค.
๊ทธ ์ด์ ๋ ๋ฌด์์ผ๊น์? JavaScript๋ ์คํฌ๋ฆฝํธ๋ฅผ ๋ถ์/์คํํ๊ณ ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ๋ฑ๋กํ๋ ์ฆ์ add๋ฅผ ์คํํ๊ธฐ ๋๋ฌธ์ ๋๋ค - ๊ดํธ๋ฅผ ์ถ๊ฐํ๊ธฐ ๋๋ฌธ์ด์ฃ => ์๋ฅผ ์ฐธ์กฐํด ์ฃผ์ธ์. "ํจ์๋ฅผ ์คํํด!".
์๋์ ๊ฐ์ด ์ฝ๋์ ์ด๋๊ฐ์ add๋ฅผ ์ถ๊ฐํ๋ ๊ฒ๋ง์ผ๋ก๋ ์๋ฌด ํจ๊ณผ๊ฐ ์์ต๋๋ค.
- let someVar = 5;
- add
- alert('Do something else...');
Why?
์๋ํ๋ฉด ํจ์์ ์ด๋ฆ๋ง ์๊ณ JavaScript์ ๋ค๋ฅธ ์ ๋ณด๋ฅผ ์ ๊ณตํ์ง ์์๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ทธ๋ฌ๋ฉด JavaScript๋ ๊ทธ ํจ์ ์ด๋ฆ์ผ๋ก ๋ฌด์์ ํด์ผ ํ๋์ง ์์ง ๋ชปํด์("ํด๋ฆญ์ด ๋ฐ์ํ ๋ ์คํํด์ผ ํ๋์? ์ด๋ ์ ๋์ ์๊ฐ์ด ์ง๋๋ฉด? ๋ชจ๋ฅด๊ฒ ์ต๋๋ค...") ๊ทธ๋ฆฌ๊ณ ๊ฒฐ๊ณผ์ ์ผ๋ก JavaScript๋ ์ด ๋ฌธ์ฅ์ ๋ฌด์ํ๊ฒ ๋ฉ๋๋ค.

Sources
https://www.freecodecamp.org/news/var-let-and-const-whats-the-difference/
Var, Let, and Const – What's the Difference?
A lot of shiny new features came out with ES2015 (ES6). And now, since it's 2020, it's assumed that a lot of JavaScript developers have become familiar with and have started using these features. While this assumption might be partially true, it's still po
www.freecodecamp.org
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
Template literals (Template strings) - JavaScript | MDN
Template literals are literals delimited with backtick (`) characters, allowing for multi-line strings, string interpolation with embedded expressions, and special constructs called tagged templates.
developer.mozilla.org
https://www.w3schools.com/js/js_scope.asp
JavaScript Scope
W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.
www.w3schools.com