Parsa Hejabi
a = b * 2
a = b * 2
b * 2;
“A general expression that stands alone is also called an expression statement”
alert ( a );
call expression statement
“It’s typically asserted that JavaScript is interpreted, because your JavaScript source code is processed each time it’s run. ”
“But that’s not entirely accurate. The JavaScript engine actually compiles the program on the fly and then immediately runs the compiled code.”
console.log(...);
“how we print text (aka output to the user) in the developer console.”
alert(...);
“Another way of creating output that you can see”
“age = prompt( "Please tell me your age:" );
console.log( age );”
“way to get input”
👎🏻
number
string
literals in '...' or "..."
boolean
null and undefined
object
symbol (new to ES6)
var a = "42";
var b = Number( a );
console.log( a ); // "42"
console.log( b ); // 42
Explicit coercion
var a = "99.99" == 99.99;
console.log(a); //true
Implicit coercion
var a;
typeof a; // "undefined"
a = "hello world";
typeof a; // "string"
a = 42;
typeof a; // "number"
a = true;
typeof a; // "boolean"
a = null;
typeof a; // "object"--weird, bug
a = undefined;
typeof a; // "undefined"
a = { b: "c" };
typeof a; // "object”
// This is a single-line comment
/* But this is
a multiline
comment.
*/
“Other languages emphasize types for values instead of variables. Weak typing, otherwise known as dynamic typing, allows a variable to hold any type of value at any time. It’s typically cited as a benefit for program flexibility”
var amount = 99.99;
amount = amount * 2;
console.log( amount ); // 199.98
// convert `amount` to a string, and
// add "$" on the beginning
amount = "$" + String( amount );
console.log( amount ); // "$199.98”
var TAX_RATE = 0.08; // 8% sales tax
var amount = 99.99;
amount = amount * 2;
amount = amount + (amount * TAX_RATE);
console.log( amount ); // 215.9784
console.log( amount.toFixed( 2 ) ); // "215.98”
// as of ES6:
const TAX_RATE = 0.08;
var amount = 99.99;
Older version of JS
ES6 version of JS
var amount = 99.99;
// a general block
{
amount = amount * 2;
console.log( amount ); // 199.98
}
“In JavaScript, a block is defined by wrapping one or more statements inside a curly-brace pair { .. }”
var amount = 99.99;
// is amount big enough?
if (amount > 10) { // <-- block attached to `if`
amount = amount * 2;
console.log( amount ); // 199.98
}
const ACCESSORY_PRICE = 9.99;
var bank_balance = 302.13;
var amount = 99.99;
amount = amount * 2;
// can we afford the extra purchase?
if ( amount < bank_balance ) {
console.log( "I'll take the accessory!" );
amount = amount + ACCESSORY_PRICE;
}
// otherwise:
else {
console.log( "No, thanks." );
}
while (numOfCustomers > 0) {
console.log( "How may I help you?" );
// help the customer...
numOfCustomers = numOfCustomers - 1;
}
// versus:
do {
console.log( "How may I help you?" );
// help the customer...
numOfCustomers = numOfCustomers - 1;
} while (numOfCustomers > 0);
// for:
for (var i = 0; i <= 9; i = i + 1) {
console.log( i );
}
// 0 1 2 3 4 5 6 7 8 9
“a collection of variables as well as the rules for how those variables are accessed by name.”
“In JavaScript, each function gets its own scope.”
“A variable name has to be unique within the same scope there can’t be two different a variables sitting right next to each other.”
function one() {
// this `a` only belongs to the `one()` function
var a = 1;
console.log( a );
}
function two() {
// this `a` only belongs to the `two()` function
var a = 2;
console.log( a );
}
one(); // 1
two(); // 2
function outer() {
var a = 1;
function inner() {
var b = 2;
// we can access both `a` and `b` here
console.log( a + b ); // 3
}
inner();
// we can only access `a` here
console.log( a ); // 1
}
outer();
“Lexical scope rules say that code in one scope can access variables of either that scope or any scope outside of it.”
const TAX_RATE = 0.08;
function calculateFinalPurchaseAmount(amt) {
// calculate the new amount with the tax
amt = amt + (amt * TAX_RATE);
// return the new amount
return amt;
}
“Lexical scope rules say that code in one scope can access variables of either that scope or any scope outside of it.”
var obj = {
a: "hello world",
b: 42,
c: true
};
obj.a; // "hello world"
obj.b; // 42
obj.c; // true
obj["a"]; // "hello world"
obj["b"]; // 42
obj["c"]; // true
var obj = {
a: "hello world",
b: 42
};
var b = "a";
obj[b]; // "hello world"
obj["b"]; // 42
var arr = [
"hello world",
42,
true
];
arr[0]; // "hello world"
arr[1]; // 42
arr[2]; // true
arr.length; // 3
typeof arr; // "object”
An array is an object. so they have some properties like length
function foo() {
return 42;
}
foo.bar = "hello world";
typeof foo; // "function"
typeof foo(); // "number"
typeof foo.bar; // "string"
object subtype.
var a = "hello world";
var b = 3.14159;
a.length; // 11
a.toUpperCase(); // "HELLO WORLD"
b.toFixed(4); // "3.1416”
String object wrapper
defines toUpperCase() method on its prototype
JS automataically "boxes" the value to its object wrapper
number can be wrapped by Number object
boolean can be wrapped by Boolean object
var a = "42";
var b = a * 1; // "42" implicitly coerced to 42 here
a; // "42"
b; // 42--the number!
/*----------------------------------------*/
console.log("ba" + NaN + "a"); // "BaNaNa"
// List of "falsy" values in JS:
"" // (empty string)
0, -0, NaN // (invalid number)
null, undefined
false
"hello"
42
true
[ ], [ 1, "2", 3 ] (arrays)
{ }, { a: 42 } (obejcts)
function foo() { .. } (functions)
"Truthy" values are any value that is not on "falsy" list
== checks for value equality with coercion allowed
=== checks for value equality without allowing coercion
var a = "42";
var b = 42;
a == b; // true
a === b; // false
If either value (or side) in a comparison could be the true or false use ===
If either value (or side) in a comparison could be of these specific values (0, "", or [ ] --empty array), use ===
In ALL other cases you're safe to use ==
Simply you can use === all the time.
Take special note of the == and === comparison rules if you're comparing two non-primitive values, like objects (including functions and arrays)
var a = [1,2,3];
var b = [1,2,3];
var c = "1,2,3";
a == c; // true
b == c; // true
a == b; // false
var a = 41;
var b = "42";
var c = "43";
a < b; // true
b < c; // true
var a = 42;
var b = "foo";
a < b; // false
a > b; // false
a == b; // false
How can all of those three comparisons be false?!!!
🤔
var a = 42;
var b = "foo";
a < b; // false
a > b; // false
a == b; // false
How can all of those three comparisons be false?!!!
For < and >: NaN! (invalid number value)
For ==: 42 == NaN is false!
var a = 2;
foo(); // works because `foo()`
// declaration is "hoisted"
function foo() {
a = 3;
console.log( a ); // 3
var a; // declaration is "hoisted"
// to the top of `foo()`
}
console.log( a ); // 2
function foo() {
var a = 1;
function bar() {
var b = 2;
function baz() {
var c = 3;
console.log( a, b, c ); // 1 2 3
}
baz();
console.log( a, b ); // 1 2
}
bar();
console.log( a ); // 1
}
foo();
function foo() {
a = 1; // `a` not formally declared
}
foo();
a; // 1--oops, auto global variable :(
Automatically created variable on the top-level global scope!
function foo() {
var a = 1;
if (a >= 1) {
let b = 2;
while (b < 5) {
let c = b * 2;
b++;
console.log( a + c );
}
}
}
foo();
// 5 7 9
“ES6 lets you declare variables to belong to individual blocks (pairs of { .. }), using the let keyword.”
var foo = function() {
console.log("1");
};
var x = function bar() {
console.log("2");
};
foo(); // 1
bar(); // Uncaught ReferenceError: bar is not defined
x(); //2
(function IIFE(){
console.log( "Hello!" );
})();
// "Hello!"
function foo() { .. }
// `foo` function reference expression,
// then `()` executes it
foo();
// `IIFE` function expression,
// then `()` executes it
(function IIFE(){ .. })();
(function IIFE(a, b){
console.log( a + b );
})(12, 15);
// 27
function makeAdder(x) {
// parameter `x` is an inner variable
// inner function `add()` uses `x`, so
// it has a "closure" over it
function add(y) {
return y + x;
};
return add;
};
// `plusOne` gets a reference to the inner `add(..)`
// function with closure over the `x` parameter of
// the outer `makeAdder(..)`
var plusOne = makeAdder( 1 );
// `plusTen` gets a reference to the inner `add(..)`
// function with closure over the `x` parameter of
// the outer `makeAdder(..)`
var plusTen = makeAdder( 10 );
plusOne( 3 ); // 4 <-- 1 + 3
plusOne( 41 ); // 42 <-- 1 + 41
plusTen( 13 ); // 23 <-- 10 + 13
function number(value) {
var x = value;
function increment() {
x++;
};
function decrement() {
x--;
};
function getValue() {
return x;
};
return {
getValue: getValue,
increment: increment,
decrement: decrement
};
};
var a = number(10);
a.getValue(); // 10
a.increment();
a.getValue(); // 11
function foo() {
console.log(this.bar);
}
var bar = "global";
var obj1 = { bar: "obj1", foo: foo };
var obj2 = { bar: "obj2" };
// --------
foo (); // "global"
obj1 . foo (); // "obj1"
foo . call ( obj2 ); // "obj2"
new foo (); // undefined
foo() ends up setting this to the global object in non-strict mode (in strict mode, this would be undefined and you’d get an error in accessing the bar property) so "global" is the value found for this.bar.
obj1.foo() sets this to the obj1 object.
foo.call(obj2) sets this to the obj2 object.
new foo() sets this to a brand new empty object.
(Specially the arrays)
Feel free to contact me on my website!