### Topics
* Operators
* var , let and const
* The __this__
* Fat arrow
* Templete literal
* Destructor
---
### JavaScript Bad Parts - 1
* Operator
* Choose `== or ===`
* Choose `!= or !==`
---
* Test yourself
```js
console.log( " 1==true : ", 1==true)
console.log( " ''==true : ", ''==true)
console.log( " '1'==true : ", '1'==true)
console.log( " \"1\"==true : ", "1"==true)
console.log( " {}==true : ", [{}]==true)
console.log( " []==true : ", ['1']==true)
```
---
```js
console.log("1==true : ", 1==true) // 1==true : true
console.log("''==true : ", ''==true) // ''==true : false
console.log("'1'==true : ", '1'==true) // '1'==true : true
console.log("\"1\"==true : ", "1"==true)// "1"==true : true
console.log("{}==true : ", {}==true) // {}==true : false
console.log("['1']==true : ", ['1']==true) // []==true : true
```
---
* Test yourself
```js
console.log( " 0==false : ", 0==false)
console.log( " 1==false : ", 1==false)
console.log( " ''==false : ", ''==false)
console.log( " '1'==false : ", '1'==false)
console.log( " \"\"==false : ", ""==false)
console.log( " {}==false : ", {}==false)
console.log( " []==false : ", []==false)
console.log( " ['0']==false : ", ['0']==false)
```
---
```js
console.log( " 0==false : ", 0==false) // 0==false : true
console.log( " 1==false : ", 1==false) // 1==false : false
console.log( " ''==false : ", ''==false) // ''==false : true
console.log( " '1'==false : ", '1'==false)// '1'==false : false
console.log( " \"\"==false : ", ""==false)// ""==false : true
console.log( " {}==false : ", {}==false) // {}==false : false
console.log( " []==false : ", []==false) // []==false : true
console.log( " ['0']==false : ", ['0']==false) // []==false : true
```
---
* Test yourself
```js
console.log( " null==false : ", null==false)
console.log( " undefined==false : ", undefined==false)
console.log( " undefined==null : ", null==undefined)
```
---
```js
console.log( " null==false : ", null==false)
// null==false: false
console.log( " undefined==false : ", undefined==false)
// undefined==false: false
console.log( " undefined==null : ", null==undefined)
// undefined==null: true
```
---
* JavaScript has both strict and type–converting comparisons. A strict comparison (e.g., ===) is only true if the operands are of the same type and the contents match. The more commonly-used abstract comparison (e.g. ==) converts the operands to the same type before making the comparison.
---
### Quiz
Compare two arrays of number are the same
---
### JavaScript Bad Parts - 2
## The **var**
---
* Test yourself
```js
function testVar(){
console.log(a)
console.log(b)
var b = 2
}
var a = 1
testVar()
console.log(b)
```
---
* Test yourself (Browser) - TBC
```js
d = 13
console.log(this.d)
delete this.d
console.log(this.d)
var e = 31
console.log(this.e)
delete this.e
console.log(this.e)
var i = i + 1
console.log( i )
console.log( this.i )
```
---
```js
var e = 31
f = 13
console.log(this.e, this.f) // 31 13
console.log(e, f) // 31 13
delete this.f
delete this.e
console.log(this.e, this.f) // 31 undefinded
console.log(e, f) // ReferenceError: d is not defined
var i = i + 1
console.log( i ) // NaN
console.log( this.i ) // NaN
```
---
Conclusion: Because of the above unexpected results, it is recommended to always declare variables, regardless of whether they are in a function or global scope.
---
* Test yourself
```js
var var1;
let letVar;
const constVar;
function testVar() {
console.log( var1);
console.log( constVar);
console.log( letVar);
}
```
---
```js
var var1;
let letVar;
const constVar; // missing initialization
function testVar() {
console.log( var1);
console.log( constVar);
console.log( letVar);
}
```
---
* Test yourself
```js
var v1 = "";
var v1 = 123;
let let1 = "";
let let1 = 123;
const c1 = "";
c1 = 123;
```
---
```js
var v1 = "";
var v1 = 123;
let let1 = "";
let let1 = 123; //SyntaxError: Identifier 'let1' has already been declared.
const c1 = "";
c1 = 123; // TypeError: Assignment to constant variable.
```
---
* Test yourself
```js
for ( var i = 0 ; i < 5 ; i++ ){
var x = 20;
console.log(i);
}
console.log( i );
console.log( x );
for ( ; i < 10 ; i++ ){
var i
console.log(i);
}
```
---
```js
for ( var i = 0 ; i < 5 ; i++ ) {
var x = 20
console.log(i);//0 1 2 3 4
}
console.log(i);//5
console.log(x);//20
for ( ; i < 10 ; i++ ){
var i// re-declare will not reset value
console.log(i);//5 6 7 8 9
}
```
---
* Test yourself
```js
for ( let t = 0 ; t < 5 ; t++ ){
console.log( t);
let s = 100
}
console.log(s)
console.log(t)
```
---
```js
for ( let t = 0 ; t < 5 ; t++ ){
console.log( t);
let s = 100
}
console.log(t)//ReferenceError: t is not defined
console.log(s)//
```
---
* let allows you to declare variables that are limited to a scope of a block statement, or expression on which it is used, unlike the var keyword, which defines a variable globally, or locally to an entire function regardless of block scope. The other difference between var and let is that the latter is initialized to value only when parser evaluates it
---
* Constants are block-scoped, much like variables defined using the let statement. The value of a constant can’t be changed through reassignment, and it can’t be re-declared. It does not mean the value it holds is immutable, just that the variable identifier cannot be reassigned.
---
### JavaScript Bad Parts - 3
## The unpredictable **this** keyword
[MDN] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this)
In most cases, the value of this is determined by how a function is called (runtime binding). It can't be set by assignment during execution, and it may be different each time the function is called.
---
* Test
```js
var obj0 = {
prop: 'obj0',
func_1: function () {
console.log(' func_1-> ', this);
var func_2 = {
prop: 'func_2',
func_3: function () {
console.log(' func_3 -> ', this);
}
};
func_2.func_3();
}
};
obj0.func_1();
```
---
* Test
```js
var obj1 = {
prop: 'obj1',
func_1: function () {
console.log(' func_1-> ', this);
func_2 = function () {
this.prop = 'func_2';
var func_3 = function () {
this.p = 'func_3';
console.log(' func_3 -> ', this);
}
return func_3
};
func_2()();
}
};
obj1.func_1();
```
---
* Test (Fat Arrow)
```js
var obj2 = {
prop: 123,
func_1: () => {
console.log(' func_1-> ', this);
func_2 = {
prop: 'func_2',
func_3: () => {
this.p = 'func_3';
console.log(' func_3 -> ', this);
}
};
func_2.func_3();
}
};
obj2.func_1();
```
---
* Test ( Binding )
```js
var obj3 = {
p: 'obj3',
toBeCalled: function () {
console.log(' this is toBeCalled ', this.p);
},
toBind: function (obj) {
obj.toBeCalled();
}
};
var testBind = obj3.toBind;
testBind(obj3);
var obj4 = {
p: 'obj4',
toBeCalled: () => {
console.log(' this is toBeCalled ', this.p);
},
toBind: obj => {
obj.toBeCalled();
}
};
var testBind2 = obj4.toBind;
testBind2(obj4);
```
---
### Arrow Function
An arrow function expression is a syntactically compact alternative to a regular function expression, although without its own bindings to the this, arguments, super, or new.target keywords. Arrow function expressions are ill suited as methods, and they cannot be used as constructors.
---
```js
const arrFunc = p1 => p2 => console.log(p1," ",p2)
arrFunc("Hello")("World")
const arrFunc2 = p1 => {
return p2 => console.log(p1," ",p2)
}
arrFunc2("Hello")("World")
```
---
### Template literal
Template literals are string literals allowing embedded expressions. You can use multi-line strings and string interpolation features with them.
---
```js
// literal
const message = `
hello
developer
${1+1}
${new Date()}
`
console.log( message)
```
---
### Destructor
```js
const person = {
name: "name",
fullName: "full name",
email: "email@test.com"
}
const testDestructor = (p) =>
{
const { name, fullName , email } = {...p};
console.log(`
name: ${name}
fullName: ${fullName}
email: ${email}
${new Date()}
`)
}
testDestructor( person )
```
---