Master your toolbelt!

About me

Catalin Andrei

dev@ACCENTURE

I work on project: "SmartHome"

I'm an open source & home automation enthusiast (aka. geek).

Member of G.R.E.E.N@ACCENTURE

What is this talk about?

The good / functions

function add(a,b){
  return a+b;
}
c = add(1,2);
console.log(c);  //prints 3

function statements

var add = function(a,b){
  return a+b;
}
c = add(1,2);
console.log(c);  //prints 3

function expressions

The good / functions

function add(a,b){
  return a+b;
}
c = add(1,2);
console.log(c);  //prints 3

function statements

var add = function(a,b){
  return a+b;
}
c = add(1,2);
console.log(c);  //prints 3

function expressions

function add(a,b){
  return a+b;
}
function calculate(passfunction,a,b){
  return passfunction(a,b)
}
c = calculate(add,1,2);
console.log(c);  //prints 3

pass them to other functions

The good / functions

function add(a,b){
  return a+b;
}
c = add(1,2);
console.log(c);  //prints 3

function statements

var add = function(a,b){
  return a+b;
}
c = add(1,2);
console.log(c);  //prints 3

function expressions

function add(a,b){
  return a+b;
}
function calculate(passfunction,a,b){
  return passfunction(a,b)
}
c = calculate(add,1,2);
console.log(c);  //prints 3

pass them to other functions

var joe = {
  say :function(){
    console.log("bang bang");
  }
}
joe.say();

as methods

The good / functions

function Actor(name) {
  this.name = name;
}
Actor.prototype.speak = function(sentence) {
  console.log(this.name + ' said ' + sentence);
}
var angelEyes = new Actor('Angel eyes');
angelEyes.speak('this is just the begining...');

var joe = new Actor('Joe');
joe.speak('of what?');

var tuco = new Actor('Tuco');
tuco.speak('of the desert.');

as constructors

The good / powerful object literal notation

    Objects in JavaScript are class free, they can be created simply by listing their components. This notation was the inspiration for JSON, the popular data interchange format.

var dog = {
    name:'dog with no name',
    food: ['wind','sand','gringos'],
    get Name() {
      return this.name;
    },
    set Name(value) {
      //I already have a name
    }
};
dog.toString = function(){
    return this.Name +' eats: '+ this.food.join(',');
};
dog.breed = 'mexican';
dog.Name = 'Chili peppers'

console.log(dog.toString())
//dog with no name eats: wind,sand,gringos

The good / prototypes

"The problem with object-oriented languages is they've got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle."
~Joe Armstrong (the inventor of Erlang)

The good / prototypes

var empty = {};
console.log(empty.toString) //Function: toString()
console.log(empty.toString()) //[Object, Object]

The good / prototypes

var empty = {};
console.log(empty.toString) //Function: toString()
console.log(empty.toString()) //[Object, Object]
Object.getPrototypeOf(Object.prototype) //null

Object.getPrototypeOf({}) == Object.prototype //true
Object.getPrototypeOf(isNaN) == Function.prototype //true
Object.getPrototypeOf([]) == Array.prototype //true

The good / prototypes

var protoRabbit = {
  eat: function(food) {
    console.log(this.type + ' rabbit eats ' + food)
  }
}

var romanianRabbit = Object.create(protoRabbit);
romanianRabbit.type = 'romanian';
romanianRabbit.eat('carrots');

var mexicanRabbit = Object.create(protoRabbit);
mexicanRabbit.type = 'mexican';
mexicanRabbit.eat('beans of course');

//romanian rabbit eats carrots
//mexican rabbit eats beans of course

The good / prototypes

function Actor(name) {
  this.name = name;
}
Actor.prototype.speak = function(sentence) {
  console.log(this.name + ' said ' + sentence);
}
var angelEyes = new Actor('Angel eyes');
angelEyes.speak('this is just the begining...');

var joe = new Actor('Joe');
joe.speak('of what?');

var tuco = new Actor('Tuco');
tuco.speak('of the desert.');

// Angel eyes: this is just the begining...
// Joe: of what?
// Tuco: of the desert.

Constructors

The good / prototypes

function Human(name) {
  this.name = name;
}
Human.prototype.speak = function(sentence) {
  console.log(this.name + ' said ' + sentence);
}

Inheritance

The good / prototypes

function Human(name) {
  this.name = name;
}
Human.prototype.speak = function(sentence) {
  console.log(this.name + ' said ' + sentence);
}

Inheritance

function Actor(name) {
  Human.call(this, name);
}
Actor.prototype = Object.create(Human.prototype);
Actor.prototype.speak = function(sentence) {
  console.log('where are my money?')
}
Actor.prototype.play = function(movie) {
  console.log(this.name + ' played in movie ' + movie);
}

The good / prototypes

function Human(name) {
  this.name = name;
}
Human.prototype.speak = function(sentence) {
  console.log(this.name + ' said ' + sentence);
}

Inheritance

function Actor(name) {
  Human.call(this, name);
}
Actor.prototype = Object.create(Human.prototype);
Actor.prototype.speak = function(sentence) {
  console.log('where are my money?')
}
Actor.prototype.play = function(movie) {
  console.log(this.name + ' played in movie ' + movie);
}
var actor = new Actor('Clint Eastwood');
actor.speak('hello everybody');
actor.play('the good, the bad & the ugly');

//where are my money?
//Clint Eastwood played in movie the good, the bad & the ugly

The bad

all money on me...

bang bang!

The bad / eval

var x = eval('3+2');
console.log(typeof x); //number

The bad / eval

var x = eval('3+2');
console.log(typeof x); //number

If a function calls eval, the interpreter cannot optimize that function!

The bad / eval

var x = eval('3+2');
console.log(typeof x); //number

If a function calls eval, the interpreter cannot optimize that function!

in the past, code inside couldn't be debugged! :-(

The bad / eval

var x = eval('3+2');
console.log(typeof x); //number
function getBlackBox() {
  eval('x=123');
  eval('add = function(a,b) {return a + b;};')

  console.log(add(1, 5)); //6
  console.log(x) //123
}

The bad / eval

var x = eval('3+2');
console.log(typeof x); //number
function getBlackBox() {
  eval('x=123');
  eval('add = function(a,b) {return a + b;};')

  console.log(add(1, 5)); //6
  console.log(x) //123
}

new variables & functions could be added in the scope!

The bad / eval

function getBlackBox() {
  'use strict' //ECMAScript 5 strict mode

  eval('x=123'); //ReferenceError: x is not defined
  eval('add = function(a,b) {return a + b;};')
}

evaluated code can query and set local variables, but cannot define new variables or functions in the local scope.

The bad / eval

function getBlackBox() {
  'use strict' //ECMAScript 5 strict mode

  eval('x=123'); //ReferenceError: x is not defined
  eval('add = function(a,b) {return a + b;};')
}

evaluated code can query and set local variables, but cannot define new variables or functions in the local scope.

function getBlackBox() {
  'use strict' //ECMAScript 5 strict mode
  
  var x, add;

  eval('x=123');
  eval('add = function(a,b) {return a + b;};')

  console.log(x, add(10, 20)); //123, 30
}

The bad / typed wrappers

var a = new Number(10);
var b = new Boolean(false);
var c = new String('Go with the flow, my friend!');

if (b) {
 console.log('this is my lucky day!')
}

console.log(a,b,c);
console.log(typeof a, typeof b, typeof c);

The bad / typed wrappers

var a = new Number(10);
var b = new Boolean(false);
var c = new String('Go with the flow, my friend!');

if (b) {
 console.log('this is my lucky day!')
}

console.log(a,b,c);
console.log(typeof a, typeof b, typeof c);

//this is my lucky day
//[Number: 10] [Boolean: false] [String: 'Go with the flow, my friend!']
//object object object

The bad / typed wrappers

var a = new Number(10);
var b = new Boolean(false);
var c = new String('Go with the flow, my friend!');

if (b == true) {
 console.log('this is my lucky day!')
}

console.log(a.valueOf(), b.valueOf(), c.valueOf());
console.log(typeof a.valueOf(), typeof b.valueOf(), typeof c.valueOf());

//10 false 'Go with the flow, my friend!'
//[Number] [Boolean] [String]

The ugly

I won a beauty contest when I was a child!

The ugly / Semicolon insertion

"Humans make mistakes. Let's try to detect omitted semicolons and insert them automatically."

~ Javascript, 1995

The ugly / Semicolon insertion

function getPerson() {
  return
  {
    name: 'Bill'
  }
}

a = getPerson()

The ugly / Semicolon insertion

function getPerson() {
  return
  {
    name: 'Bill'
  }
}

a = getPerson()
function getPerson() {
  return;
  {
    name: 'Bill'
  }
}

a = getPerson() //undefined

The ugly / Semicolon insertion

function getPerson() {
  return
  {
    name: 'Bill'
  }
}

a = getPerson()
function getPerson() {
  return;
  {
    name: 'Bill'
  }
}

a = getPerson() //undefined
function getPerson() {
  return {
    name: 'Bill'
  }
}

a = getPerson() // { name: 'Bill' }

The ugly / Equality operations

"JavaScript has two sets of equality operators: === and !==, and their evil twins == and !=."
~Douglas Crockford

The ugly / Equality operations

'' == '0'

The ugly / Equality operations

'' == '0' // false

The ugly / Equality operations

'' == '0' //false
0 == ''

The ugly / Equality operations

'' == '0' //false
0 == '' //true

The ugly / Equality operations

'' == '0' //false
0 == '' //true

The ugly / Equality operations

'' == '0' //false
0 == '' //true
0 == '0'

The ugly / Equality operations

'' == '0' //false
0 == '' //true
0 == '0' //true

The ugly / Equality operations

'' == '0' //false
0 == '' //true
0 == '0' //true

false == 'false'

The ugly / Equality operations

'' == '0' //false
0 == '' //true
0 == '0' //true

false == 'false' //false

The ugly / Equality operations

'' == '0' //false
0 == '' //true
0 == '0' //true

false == 'false' //false
false == '0'

The ugly / Equality operations

'' == '0' //false
0 == '' //true
0 == '0' //true

false == 'false' //false
false == '0' //true

The ugly / Equality operations

'' == '0' //false
0 == '' //true
0 == '0' //true

false == 'false' //false
false == '0' //true
null == undefined

The ugly / Equality operations

'' == '0' //false
0 == '' //true
0 == '0' //true

false == 'false' //false
false == '0' //true
null == undefined //true

The ugly / Equality operations

'' == '0' //false
0 == '' //true
0 == '0' //true

false == 'false' //false
false == '0' //true
null == undefined //true

In conclusion, dont use the evil twins!

They bite ...sometimes!

The ugly / Scoping

JavaScript’s syntax comes from C. In all other C-like languages, a block (a set of
statements wrapped in curly braces) creates a scope.

The ugly / Scoping

var x = 5
if (true) {
  var y = 10
}
console.log(x + y)

The ugly / Scoping

var x = 5
if (true) {
  var y = 10
}
console.log(x + y) //15

The ugly / Scoping

var x = 5
if (true) {
  var y = 10
}
console.log(x + y) //15
var x = 5
function test() {
  var y = 10
}
console.log(x + y)

The ugly / Scoping

var x = 5
if (true) {
  var y = 10
}
console.log(x + y) //15
var x = 5
function test() {
  var y = 10
}
console.log(x + y) //y is not defined

The ugly / Scoping

var x = 5
if (true) {
  var y = 10
}
console.log(x + y) //15
var x = 5
function test() {
  var y = 10
}
console.log(x + y) //y is not defined
let x = 5
if (true) {
  let y = 10
}
console.log(x + y) //y is not defined

The ugly / Scoping

Global scope

//Global Scope
var a = 1; //window.a = 1
function scopeTest() {
  console.log(a);
}
scopeTest();  //1

The ugly / Scoping

Global scope

//Global Scope
var a = 1; //window.a = 1
function scopeTest() {
  console.log(a);
}
scopeTest();  //1
//Global Scope
var a = 1;
function scopeTest() {
  a = 2; //Overwrites global variable 2, you omit 'var'
  console.log(a);
}
console.log(a); //1
scopeTest();  //2
console.log(a); //2 (global value is overwritten)

The ugly / Scoping

Global scope

//Global Scope
var a = 1; //window.a = 1
function scopeTest() {
  console.log(a);
}
scopeTest();  //1
//Global Scope
var a = 1;
function scopeTest() {
  a = 2; //Overwrites global variable 2, you omit 'var'
  console.log(a);
}
console.log(a); //1
scopeTest();  //2
console.log(a); //2 (global value is overwritten)
//Global Scope
var a = 1;
function scopeTest() {
  var a = 2;
  console.log(a);
}
console.log(a); //1
scopeTest();  //2
console.log(a); //1

The ugly / Scoping

function Actor(name) {
  this.name = name
}

Actor.prototype.logMovies = function(movies) {
  return movies.map(function(movie) {
    console.log(this.name + ' played in the movie ' + movie)
  })
}

var actor = new Actor('Clint Eastwood')
actor.logMovies(['The Good, the Bad and the Ugly', 'Invictus'])

The ugly / Scoping

function Actor(name) {
  this.name = name
}

Actor.prototype.logMovies = function(movies) {
  return movies.map(function(movie) {
    console.log(this.name + ' played in the movie ' + movie)
  })
}

var actor = new Actor('Clint Eastwood')
actor.logMovies(['The Good, the Bad and the Ugly', 'Invictus'])

/*  */
undefined played in the movie The Good, the Bad and the Ugly
undefined played in the movie Invictus

The ugly / Scoping

function Actor(name) {
  this.name = name
}

Actor.prototype.logMovies = function(movies) {
  var self = this;
  return movies.map(function(movie) {
    console.log(self.name + ' played in the movie ' + movie)
  })
}

var actor = new Actor('Clint Eastwood')
actor.logMovies(['The Good, the Bad and the Ugly', 'Invictus'])

/*  */
Clint Eastwood played in the movie The Good, the Bad and the Ugly
Clint Eastwood played in the movie Invictus


The ugly / Scoping

function Actor(name) {
  this.name = name
}

Actor.prototype.logMovies = function(movies) {
  return movies.map(function(movie) {
    console.log(this.name + ' played in the movie ' + movie)
  }, this)
}

var actor = new Actor('Clint Eastwood')
actor.logMovies(['The Good, the Bad and the Ugly', 'Invictus'])

/*  */
Clint Eastwood played in the movie The Good, the Bad and the Ugly
Clint Eastwood played in the movie Invictus


The ugly / Scoping

function Actor(name) {
  this.name = name
}

Actor.prototype.logMovies = function(movies) {
  return movies.map(function(movie) {
    console.log(this.name + ' played in the movie ' + movie)
  }.bind(this))
}

var actor = new Actor('Clint Eastwood')
actor.logMovies(['The Good, the Bad and the Ugly', 'Invictus'])

/*  */
Clint Eastwood played in the movie The Good, the Bad and the Ugly
Clint Eastwood played in the movie Invictus


The ugly / Scoping

function Actor(name) {
  this.name = name
}

Actor.prototype.logMovies = function(movies) {
  return movies.map(movie =>
    console.log(this.name + ' played in the movie ' + movie)
  )
}

var actor = new Actor('Clint Eastwood')
actor.logMovies(['The Good, the Bad and the Ugly', 'Invictus'])

/*  */
Clint Eastwood played in the movie The Good, the Bad and the Ugly
Clint Eastwood played in the movie Invictus


The ugly / Hoisting

Hoisting is JavaScript's default behavior of moving declarations to the top.

The ugly / Hoisting

x = 5; // Assign 5 to x

elem = document.getElementById("demo"); // Find an element
elem.innerHTML = x;                     // Display x in the element

var x; // Declare x 
var x; // Declare x
x = 5; // Assign 5 to x

elem = document.getElementById("demo"); // Find an element
elem.innerHTML = x;                     // Display x in the element

The ugly / Hoisting

var x = 5; // Initialize x

elem = document.getElementById("demo"); // Find an element
elem.innerHTML = x + " " + y;           // Display x and y

var y = 7; // Initialize y 
var x = 5; // Initialize x
var y = 7; // Initialize y

elem = document.getElementById("demo"); // Find an element
elem.innerHTML = x + " " + y;           // Display x and y 

Thank you!

Questions & answers

Copy of Javascript - the good, the bad, the ugly

By jonattfin

Copy of Javascript - the good, the bad, the ugly

  • 945