[Go to site: main page, start]

0% found this document useful (0 votes)
5 views9 pages

JavaScript Basics: Variables & Data Types

The document provides an overview of JavaScript basics, including the differences between compiled and interpreted languages, variable declarations, primitive data types, and object-oriented programming without classes. It covers function declarations, expressions, arrow functions, high-order functions, and the use of spread and rest operators. Additionally, it explains how JavaScript handles data types and the concept of hoisting in function declarations.

Uploaded by

deepbiswasrepo
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views9 pages

JavaScript Basics: Variables & Data Types

The document provides an overview of JavaScript basics, including the differences between compiled and interpreted languages, variable declarations, primitive data types, and object-oriented programming without classes. It covers function declarations, expressions, arrow functions, high-order functions, and the use of spread and rest operators. Additionally, it explains how JavaScript handles data types and the concept of hoisting in function declarations.

Uploaded by

deepbiswasrepo
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Notes scribed by Deep Biswas, CS355:

Tues/Thurs 5PM, Spring '22

C1, C2: JavaScript Basics


JavaScript: (“primarily”) an interpreted language that has been integrated within all
web browsers, thuss, comes preinstalled in every operating system.

Compiled Languages comprise of code fed into a software known as the compiler, which
runs the code, performs optimizations on unnecessary instructions, and compiles it
into an executable (.exe) file. You can share the program simply by distributing the
executable file. Compiled languages include C, C++.

Interpreted Languages comprise of another software, known as the interpreter, which


reads in code sequentially, line-by-line producing output accordingly. In order to
follow this strict protocol, it cannot make optimizations (which are instead up to the
engineers - producing optimized code.) Because of the lack of optimization, many
programs resolve and output much faster. Sharing interpreted programs require the code
and the interpreter you get from the languages installation, ex: when running Java,
programs of an interpreted language, you’d need the interpreter provided through
installation(s) of JRE/JDK in order to run those programs.

However, through running optimization, compiling may sometimes resolve faster with an
output, such as circumstances where several lines of code can simply be skipped
instead of ran. For this clause, JavaScript, is also (“sometimes”) considered
compiling in some definitions, because its modern-day engines comprise of both a
compiler, and an interpreter to bypass this execution loophole. Through having both
these software, depending on whatever outputs the fastest, it provides either the
compiled or interpreted result.

The JavaScript Engine runs the compiling process, starting immediately at the first
line read in by the interpreter (which then sends a copy of the code into the
compiler), and then they run in tandem until the first result gets outputted, after
which the leftover process is stopped, and either interpreted/compiled result is
executed.

JavaScript exists both on the web as browser JavaScript, and standalone via [Link].
You can easily access Browser JavaScript, on any web browser, by opening the
inspection/developer tools ( ctrl + shift + i , on Google Chrome), containing the
console.

The console contains a full JavaScript Interpreter, for all your browser only
JavaScript needs, including testing specific APIs, altering web pages. Browser
JavaScript isn't intended for features such as I/O File Access, a scenario where you
are recommended to run standalone JavaScript by installing NodeJS.

Variable Declaration
In JavaScript initializing variables involve using declarations such as var, const,
let. These declarations specify the variables’ accessibility and lifespan during the
execution of the program. let signifies that a variable is Block Scoped(Lexical
Scoped), persisting only in the duration of the block contained between any set of
curly braces {}.

1| if (true){
2| let x = 1;
3| }
4| [Link](x);

The keyword let for the declaration in line 2, reveals that variable x is defined
block level, only available inside the block of the if statement inside the curly
braces. Therefore, after the if statement completes execution, x no longer exists as
defined, and attempting to print it out on line 4, results in a ReferenceError.

1| let c;
2| function add_a_and_b(a, b){
3| c = a + b;
4| return c;
5| }
6| [Link](add_a_and_b(3,5));
7| [Link](c);

However, since we define the variable c before the function add_a_and_b over here, it
can now access c (now existing in the call stack) inside and outside the function. It
gets modified inside the function but also persists onto the variable c, and we are
able to see this modified result outside, after the function finishes executing. The
function's inner scope (from lines 2-5) actually exists along with variable C, in the
outer scope it was defined in, and thus we will access it anywhere within there,
except outside of it.

const also signifies a variable is block-scoped, but now additionally is constant, so


the variable cannot be further reassigned and will be a unique constant.

1| const x = 1;
2| x = 0;
3| [Link](x);

Since variable x is defined in a const block scope and assigned the number 1, the
program would not be able to reassign it in line 2, raising a TypeError: Assignment to
constant variable.

Primitive Datatypes in JavaScript


As variables in JavaScript are dynamically typed, allowing you to specify what exactly
the datatype of a variable should be through passing in any type of data, which it
will then try recognizing.

There are 7 primitive types of data that JavaScript recognizes immediately:

Number: Numeric data that must fall under IEEE 754 Double standard.
String: Multi-character/text based data .
Boolean: Truth values such as true/false values.
Symbol: Universally unique values, often used to define objects’ properties.
Undefined: A state for variables which allows for JavaScript to keep track of
variables that are declared and uninitialized, (you may see it as a variable
that is pending a value of any type).
Null: A falsey value mainly kept under the hood. It just null, with only one
value, null, used to indicate absence(s) of data/objects. When a null value is
returned from a function, it's because whatever data that was intended to be
returned, could not be returned.
BigInt: Arbitrarily large integers, that exceed the maximum number permissible,
which can be found via Number.MAX_Value (1.7976931348623157e+308).

let dog1=”None”; //I have a dog named “None”-> String Value


let dog2=null; //I do NOT have a dog (the existence of my dog is null)-> Null Value
let dog3; //I have a dog, (but it is yet to be named)->Undefined Value

Ex: Where keyword left of “Value” is the primitive datatype.

Object-Oriented JavaScript (without necessity for


classes)
JavaScript renders the ability to create objects without needing class definitions.
They can simply be made:

let myDog = {name: “Sparky”, age: 1};


[Link]([Link]);

With an object name, and whatever members exist enclosed between curly braces. Though
classes still exist and are recommended for implementing more complex object-oriented
programming.

The .(dot) operator is used to access members of objects. Recall, we already refer to
members (both functions and variables) for classes defined in external libraries via
‘.’, such as [Link]() , [Link]() and Numbers.MAX_VALUE .

Regarding the above myDog class: we can access the name variable, a member of the
object, “myDog” via . + name, then in order to print it, we call upon the log()
function in the console class library. We used the dot operator, to access a function
from an external class library, to print the “name” member of our class myDog.

In JavaScript, everything is considered an object,


including primitive data-values, meaning we can use the
dot operator and access members defined for the object
classes of these primitive data types.

let str = “hello”;


[Link]();

prints numeric 5 but line 2 is computed as following: String(str).length(); where


variable str is casted into a String object, and then accesses the member function
“length.”
let x = 5;
[Link]();

prints 5, as a string, but line 2 is computed as following: Number(x).toString();


where variable x, gets casted into a Number object, and then calls the member
function, toString(); upon it.

What's going on under the hood, is that JavaScript is


casting data, into object versions of their datatype,
giving access to these members, which are then executable
via dot operator.

TypeOf is a keyword operator returning the string representation of the datatype of


any variable, whenever necessary.

let x;
typeof x;

prints 'undefined'

x = 5;
typeof x;

prints 'number'

typeof typeof x;

prints 'string', it's typeof running on what returns from typeof x, which returns a
string

typeof [1,2,3];

prints 'object'

typeof {name: "bob");

prints 'object'

let x = printx = (x) => x;


typeof x;

prints 'function'

let z = null;
typeof z;

prints 'object', (basically it is a null object)

Further intricacies of .toString()


As toString() is a member function of the Number object class (adhering IEEE 754
Double Standards - basically decimal numbers: numbers having only one decimal place,
at least somewhere) we are able to directly call invoke the function on the
appropriate data, without needing to assign into a declared variable. Ex:
[Link](); prints '1.546' 123..toString(); prints '123'(omitting decimal at
the end)

Numbers that do not have one decimal are unable to be recognized and thus will not be
able to make use of the toString() member function, unless you manually cast them as
Number objects. Number(1).toString(); prints '1'

Functions in JavaScript
There are multiple ways to implement functions in JavaScript.

Functions are declared and then invoked/called in the following format:

function add_a_and_b(a,b){
return a + b;
}

JavaScript offers “hoisted” function declarations, meaning all proper function


declarations are moved to the very top of the program, when read through the
interpreter/compiler.

function funciton_01(){
let x = 1;
return x;

};
[Link](function_01());

provides the same result as:

[Link](function_01());
function function_01(){
let x = 1;
return x;
};

Though function_01 was declared below where it is called, it is able to execute as


under the hood. The interpreter/compiler moves all declarations to the very top of the
execution. Function Expressions are the assigning of functions onto variables/objects.
This feature allows functionscgetting passed into other functions as parameters.
Function Expressions are written in the same format as variables are, with the
declaration of the variable, variable/function (in this case) name, and then
assignment into the function:

const function_02 = function function_02(){


let x = "Hello";
return x;
};
[Link](function_02());//prints Hello.
Since we already name the object/variable, writing the name for the function can be
omitted, as the function will be known via that name:

const function_02 = function(){


let x = "Hello";
return x;
};
[Link](function_02());//prints Hello

Asides the benefits of objects/variables getting assigned function, the drawback is


that these are not hoisted by JavaScript and must be written before they are called in
the scope.

Arrow Functions are another variation of function expressions, that allow for more
concise operations. They are called arrow functions, due to the usage of the fat arrow
(=>) which comes after the parentheses of parameters. Here is the format:

const function_04 = (a,b) => a + b;


[Link](function_04(1,6));//prints 7

By keeping everything to a minimum of one-line, we can make arrow-functions one-


liners, without even needing curly braces ({}) or a return statement.

However, when this boundary is surpassed, you must incorporate both curly braces and a
return statement, and this makes it not much different from regular function
expressions, which require curly braces and a return statement.

const function_05 = function(a,b){


let c = a + b;
return c;
};
[Link](function_05(1,6));//prints 7

Creating arrow functions without parameters requires you to still include the
parentheses:

const function_05 = () = >"Hello"; //prints Hello when [Link]'ed

Here are the Syntax Errors thrown when attempting to omit the parenthesis for an arrow
function with no parameters:

const function_07 => "Hello";

Uncaught SyntaxError: Missing initializer in const declaration

const function_07 = => "Hello";

Uncaught SyntaxError: Unexpected token '=>'

However, when requiring only one parameter, you are free to omit the parenthesis
around it:

const function_08 = x => x;


[Link](function_08("Hello")); //prints "Hello"
const squareRoot = x => [Link](x);
[Link](squareRoot(25));

Factory Functions are functions that simply return a new object:

function create_adder(x){
return function(y){
[Link](typeof (x+y));
return x + y;
};
}
const add_by_eight = create adder(8);
[Link](add_by_eight(2));

prints "number" from the [Link] inside the function, and then the result of the
function call of add_by_eight(2), 10. Create_adder returns a factory function that
returns a new number object (x+y). The function being returned here is also considered
a new object in JavaScript, therefore, by definition create_adder is also considered a
factory function.

High Order Functions are functions operating on other functions, which allows for
extended interactions with larger datasets.

.map() takes in elements present in a collection/array and maps them (via the
computation/function call) into another value. It is a common function applied
to most high-order functions, and is one itself, as it always incorporates some
type of computation in the form of another function passed in or blocks of
instructions.

const function_04 = (a,b) => a+b;


let input = [1,2,3,4,5,6,7,8,9];
let output = [Link](function_04);
[Link](output);

The function Output is a function made up of the function calls of function_04


defined at the top, which is mapped onto every element in the array.

let input = [1,2,3,4,5,6,7,8,9];


let output = [Link]([Link]);
[Link](output);
// prints [1, 1.414213..., 1.732050..., 2, 2.236068..., 2.449489...,
2.645751..., 2.828427..., 3]

The function Output here is made up of the function calls of square root, which
are then mapped on to every element in the array.

Spread and Rest Operators


Through the triple dot (…) operator, JavaScript provides two ideal functions
for dealing with lists, arrays, or larger sets of data.

Rest is when we implement the … operator inside ONLY function declarations and
expressions as a parameter, enabling the function to read in an arbitrary
number of arguments as an array, which can be further interacted with.

function summation(...rest){
let sum = 0;
[Link](x => sum += x);
[Link](rest);//print and check the input array
return sum;
}
[Link](summation(1,2,3,4,5,6,7,8,9));

First prints the inputs as an array: [1,2,3,4,5,6,7,8,9] and finally prints the
sum: 45. Upon function call, the input is stored into an array that is a rest
object, which is then further interacted with.

[Link] is essentially an iterator for arrays, allowing you to perform


instructions on each element sequentially, (similar to a for each loop). Over
here, we consider each element of the rest array, arbitrarily named element x,
and add it onto our sum variable.

Spread is when we use the … operator for cases such as function calls, not in
function declarations or expressions. It is essentially the exact inverse of
rest, where now it takes an array and turns it into a parameter list. Ex: We
can pass multiple parameters into the [Link] function:

[Link]([Link](1,2,3,4)); //prints 4

Now let's try passing in an array...

let arr = [5,9,6,8,1,3,10,2];


[Link](arr); //prints NaN

However, this function cannot take in solid arrays to properly compute and
returns NaN, because it received a non-numeric argument, an array. We need to
be able to take the array, and parse only the arguments in, without having to
manually write .forEach , which is exactly why we “spread” the array into its
parameter list, which passes in properly.

let arr = [5,9,6,8,1,3,10,2];


[Link]([Link](...arr));

Spread can be used in the function calls of functions defined with the rest
usage (in the function declarations and/or expressions) of … , basically cases
where you’d expect parameters to be an arbitrary list.

As Spread converts from array object into parameter lists, we can use it to print the
elements of an array:

[Link](...[1,2,3,4]);//prints 1 2 3 4

Another use for this, would be to “augment” a subarray onto the array it is contained
in:

[Link]([1,2,3,...[4,5,6],7,8,9]); //which prints the array [1, 2, 3, 4, 5, 6, 7,


8, 9]
// the inner array [4,5,6] gets turned into a parameter list, and added on the outer
array, in the exact order everything is consecutively placed.

You might also like