JavaScript

What is JavaScript?

  • JavaScript is a dynamic, weakly typed programming language that is compiled at runtime.
  • JavaScript was created to make web pages dynamic.
  • Originally was called LiveScript but due to the popularity of Java, it was renamed JavaScript.
  • JavaScript is totally independent of Java and has nothing in common with Java.

How do webpages work?

Browsers' JavaScript Engine

  • Chrome: V8:
    V8 is Google’s open-source high-performance JavaScript and WebAssembly engine, written in C++. It is used in Chrome and in Node.js, among others. It implements ECMAScript and WebAssembly, and runs on Windows 7 or later, macOS 10.12+, and Linux systems that use x64, IA-32, ARM, or MIPS processors. V8 can run standalone or can be embedded into any C++ application.
  • Firefox: SpiderMonkey:
    SpiderMonkey is Mozilla’s JavaScript and WebAssembly Engine, used in Firefox, Servo , and various other projects. It is written in C++, Rust, and JavaScript. You can embed it into C++ and Rust projects, and it can be run as a stand-alone shell.

How is JavaScript executed?

  • JavaScript Engine > Parse Code > Compile to Machine Code > Execute Machine Code

JavaScript runs on a host environment

Browser Side:

  • JavaScript was invented to create more dynamic websites by executing in the browser!
  • JavaScript can manipulate the HTML code, CSS, send background Http request & much more.
  • JavaScript CAN’T access the local filesystem, interact with the operating system, etc.

 

Other (e.g. Server-Side):

  • Google’s JavaScript Engine (V8) was extracted to run JavaScript anywhere(called “Node.js”)
  • Node.js can be executed on any machine and is therefore often used to build web backends (Server-Side JavaScript)
  • Node.js CAN access the local filesystem, interact with the operating system, etc. It CAN’T manipulate HTML or CSS.

A brief overview of the JavaScript History

  • 1995: Netscape introduces “LiveScript” / “JavaScript”
  • 1996: Microsoft releases its own version for IE
  • Late 1996: JavaScipt submitted to ECMA International to start standardization
  • 1997 – 2005: Standardization efforts, Microsoft didn’t really join and support the standardized JS version though.
  • 2006 – 2011: Huge progress in the JavaScript ecosystem, Microsoft eventually joined forces.

Variables and Constants

				
					// Varaiables:
let userName = "Hoomaan";   // A data container/data storage
userName = "Shazdeh"        // ...Where the value can change

// Constants:
const totalUsers = 15;      // A data container/data storage
totalUsers = 20;            // ...Where the value must not change. You'll get error.
				
			
  • Use constants as often as possible.

Variables Naming:

  • Best practice: camelCase (example: userName)
  • JavaScript is case-sensitive.
  • Only letters and digits are allowed.
  • Starting with $ is allowed (example: $kindOfSpecial)
  • Starting with _ (underscore) is allowed (example: _internalValue)

 

  • user_name is allowed but bad practice!
  • Starting digits are not allowed. (example: 21Players)
  • No special characters are allowed.
  • Keywords are not allowed. (example: let let)

Data Types

  • Numbers: Important for calculation and codes where you use numbers.
  • Strings: Important for outputting results, gathering inputs.
  • Booleans: Important for conditional code and situations where you have only two choices/options.
  • Objects: Important for grouped/related data, help you with organizing data.
  • Arrays: Important for list data, an unknown amounts of data.
  • undefined: Default value of uninitialized variables.
  • null: To reset or clear a variable.
				
					// Numbers
2, -4, 24.57474

// Strings
'Hi', "Hi", `Hi` // You can use variables in the `` sign in this way:`${variable}` --> Template Literal

// Booleans
true, false

// Objects
{ name: 'Shazdeh', age: 12 }

// Arrays
[1, 2, 3, 4]
				
			
  • Line break: \n
  • more about Template literals (Template strings)
  • You should never assign undefined to a variable manually.
  • NaN: Not a Number. This is not a data type. Technically, it’s a type of number and can be used in calculations.
    It yields a new NaN and it’s the result of invalid calculations (e.g. 3 * ‘hi’)

How to find type of a variable?

				
					typeof 'Shazdeh';   // String
typeof 12;          // Number
typeof undefined;   // Undefined
typeof NaN;         // Number
typeof [1, 2, 3];   // Object
typeof {age: 23}    // Object
typeof null;        // Object
typeof true;        // Boolean
				
			

Functions

				
					function greetUser(name) {
    alert('Hi' + name);
}

// Keyword: function
// Function name: greetUser (The value before paranthesis)
// Function parameter: name (The value inside parathesis)
// Function body: everything between curly braces { }.
				
			
  • You can (but don’t have to) use parameters(e.g. name).
  • You can (but don’t have to) return values(via return).
  • After the functions, don’t use a semicolon (;).
  • the parameters are only useable inside the body of the function.
				
					function greetUser("Hoomaan");
// Call a function that needs parameter.

function logout();
// Call a function that doesn't need parameter.
				
			

You can (but don’t have to) use parameters(e.g. name).

You can (but don’t have to) return values(via return)

Global and Local scope

  • You CAN’T use local/block-scope variables (=declared inside of the functions) outside of them.
  • Functions have full access to their surrounding context, so to all the variables and so on that are defined above them or outside of them.
  • What you define inside of a function is only available in there. The ONLY way of kinda getting it out is by returning it.

Shadowed Variables

What happens if you have this code?

				
					let userName = 'Max';
function greetUser(name) {
  let userName = name;
  alert(userName);
}
userName = 'Manu';
greetUser('Max');
				
			

This will actually show an alert that says

'Max' (NOT 'Manu').

You might’ve expected that an error gets thrown because we use and declare userName more than once – and as you learned, that is not allowed.

It indeed is not allowed on the same level/ in the same scope.

So this would fail:

				
					let userName = 'Max';
let userName = 'Manu';
				
			

Why does it work in the first code snippet though?

Because we first create a global variable userName via

				
					let userName = 'Max';
				
			

But then we never re-declare that on the global level (that would not be allowed).

We only declare another variable inside of the function. But since variables in functions get their own scope, JavaScript does something which is called “shadowing”.

It creates a new variable on a different scope – this variables does not overwrite or remove the global variable by the way – both co-exist.

When referring to userName inside of the greetUserfunction we now always refer to the local, shadowed variable. Only if no such local variable existed, JavaScript would fall back to the global variable.

The "return" statement

  • The return statement just ends the function execution.
  • You can’t return nothing.

"Indirect" vs "Direct" Function

It can be confusing to see that there seem to be two ways of executing a function:

				
					function add() {
  something = someNum + someOtherNum;
}
				
			

add() vs add

It’s important to understand why we have these “two ways”!

In general, you call a function that you defined by using its name (e.g. add) and adding parentheses (with any parameters the function might need – or empty parentheses if no parameters are required like in the above example).

=> add()

This is how you execute a function from your code. Whenever JavaScript encounters this statement, it goes ahead and runs the code in the function. Period!

Sometimes however, you don’t want to execute the function immediately. You rather want to “tell JavaScript” that it should execute a certain function at some point in the future (e.g. when some event occurs).

That’s when you don’t directly call the function but when you instead just provide JavaScript with the name of the function.

=> someButton.addEventListener('click', add);

This snippet would tell JavaScript: “Hey, when the button is clicked, go ahead and execute add.”.

someButton.addEventListener('click', add()); would be wrong.

Why? Because JavaScript would encounter that line when it parses/ executes your script and register the event listener AND immediately execute add – because you added parentheses => That means (see above): “Please execute that function!”.

Just writing add somewhere in your code would do nothing by the way:

				
					let someVar = 5;
add
alert('Do something else...');
				
			

Why?

Because you just throw the name of the function in there but you don’t give any other information to JavaScript. It basically doesn’t know what to do with that name (“Should I run that when a click occurs? After a certain amount of time? I don’t know…”) and hence JavaScript kind of ignores this statement.

Mixing Numbers & Strings

				
					parseInt();     // Define the type of the input as a number without decimal. Instead of parsInt we can use plus symbol +
parseFloat();   // Define the type of the input as a number with decimal.
.toString()     // Convert the value to string. (e.g. data.toString())
				
			

You saw the example with a number and a “text number” being added

3 + '3' => '33'

in JavaScript.

That happens because the + operator also supports strings (for string concatenation).

It’s the only arithmetic operator that supports strings though. For example, this will not work:

'hi' - 'i' => NaN

NaN is covered a little later, the core takeaway is that you can’t generate a string of ‘h’ with the above code. Only + supports both strings and numbers.

Thankfully, JavaScript is pretty smart and therefore is actually able to handle this code:

3 * '3' => 9

Please note: It yields the number (!) 9, NOT a string '9'!

Similarly, these operations also all work:

3 - '3' => 0

3 / '3' => 1

Just 3 + '3' yields '33' because here JavaScript uses the “I can combine text” mode of the + operator and generates a string instead of a number.

Comments in JavaScript

				
					// This is a one line comment!

/*  This is a multiline comment!
    Line 2 of the comment!
    Line 3 of the comment!
    and so on...
*/

alert('Hello Shazdeh!') // This is an inline comment!
				
			

Operators

				
					// All thhe two following pairs of lines are the same for + - / * operators
result = result + 15;
result += 15;

result = result - 15;
result -= 15;

result = result * 15;
result *= 15;

result = result / 15;
result /= 15;
				
			
				
					// All thhe two following pairs of lines are the same for + - operators
result = result + 1;
result++;   // Increment operator

result = result - 1;
result--;   // Decrement operator
				
			

We can also use ++ and — before the variable. The difference is if you return the output:

  • Before the variable (e.g ++result): The output is the altered variable.
  • After the variable: The output is the variable before the change.
				
					result = 15;
result++;   // = 15
++result;   // = 16

result = 15;
result--;   // = 15
--result;   // = 14
				
			

Arrays

				
					let enteredData = [];   // Initiallize an empty array.

enteredData.push('data1');  // Add 'data1' to the array. Now the array is equal to: ['data1']

// Access to a specific elements of an array, e.g the second elemtnt:
enteredData[1]; // Element numbers start from 0, so the second element is qual to 1.
				
			

Objects

				
					const user = {
    name: 'Max',
    age: 30
};
				
			
  1. You use {} to “group the data” – a semicolon (;) is used after the closing }. On functions, we didn’t do that. As a rule of thumb, you can keep in mind that a semicolon is used after {} if the {} are on the right side of the equal sign!

  2. key-value pairs are separated via a comma (,), NOT via a semicolon. Using a semicolon inside of an object (i.e. between {}), would be a syntax error!

  3. Values are assigned to keys/ properties via a colon (:), NOT via an equal sign (=). Using an equal sign inside of an object (i.e. between {}), would be a syntax error!

I.e. this would be WRONG and would throw an error:


const worstPossibleUser = {
name = 'Max';
age = 30;
};
				
					// To access a specific data in an object use the name of the object followed by dot (.) to access the properties of the object:

user.name;
				
			

Importing JavaScript Files

Different Ways of Adding JavaScript to a Page

Inline JavaScript Code
				
					<script>
    alert('Hi there!');
</script>
				
			
  • Executed directly when the browser (HTML parser) reaches this tag
  • Typically only used for very trivial sites/ scripts (you’d create a huge HTML file otherwise)
External / Imported JavaScript Files
				
					<script src="someFile.js"></script>
<script src="otherFile.js"></script>
<script src="otherFile.js"></script>
				
			
  • Requested & loaded when the browser (HTML parser) reaches this tag
  • Execution behavior depends on configuration: async and defer allow HTML parser to continue

How To Import Your Scripts

Inline
				
					<script>
    alert(‘Hi!’);
</script>
				
			

Immediately executed, blocks HTML parsing & rendering.

External File
				
					<script src=“file.js”></script>
				
			

Immediatley loaded & executed, blocks HTML parsing & rendering.

External File (async)
				
					<script src=“file.js” async></script>
				
			

Immediately loaded & executed thereafter, blocks HTML parsing & rendering.

External File (defer)
				
					<script src=“file.js” defer></script>
				
			

Immediatley loaded & executed after HTML parsing & rendering.

Timeline Summary

Leave a Reply