JavaScript

The good, the bad, the ugly!

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?

JavaScript

What is this talk about?

JavaScript

history

What is this talk about?

JavaScript

reasons to learn it

history

What is this talk about?

JavaScript

reasons to learn it

history

crash course

History

developed by Brendan Eich (in 10 days  / May 1995)

History

developed by Brendan Eich (in 10 days  / May 1995)

shipped as "Live Script" with NN 2.0

History

developed by Brendan Eich (in 10 days  / May 1995)

shipped as "Live Script" with NN 2.0

Java was highly promoted, so they changed the name to JavaScript :-) clever thing for sure!

History

developed by Brendan Eich (in 10 days  / May 1995)

shipped as "Live Script" with NN 2.0

Java was highly promoted, so they changed the name to JavaScript :-) clever thing for sure!

standardized as ECMAScript in June 1997.

History

developed by Brendan Eich (in 10 days  / May 1995)

shipped as "Live Script" with NN 2.0

Java was highly promoted, so they changed the name to JavaScript :-) clever thing for sure!

standardized as ECMAScript in June 1997.

2009 Node.Js was created (Ryan Dahl).

History

developed by Brendan Eich (in 10 days  / May 1995)

shipped as "Live Script" with NN 2.0

Java was highly promoted, so they changed the name to JavaScript :-) clever thing for sure!

standardized as ECMAScript in June 1997.

2009 Node.Js was created (Ryan Dahl).

ES2015 was ratified (June 2015). ES2015 is the first major update since ES5 (2009).

WHY?

WHY?

JavaScript has been the Language of the Web, since the earliest days of the Netscape Navigator.

WHY?

JavaScript is the most popular language on the web and open source ecosystem.

WHY?

The Node package repository has the biggest number of packages (~267.410 / avg. growth 428/day).

WHY?

JavaScript's popularity and importance can be attributed to its association with the browser. Google's V8 and Mozilla's SpiderMonkey are extremely optimized JavaScript engines that power Google Chrome and Mozilla Firefox browsers, respectively.

WHY?

modern databases such as MongoDB and CouchDB use JavaScript as their scripting and query language

WHY?

Node.js is an open-source, cross-platform runtime environment for developing server-side Web applications.  Developers can write new modules in JavaScript. The runtime environment interprets JavaScript using Google's V8 JavaScript engine.

WHY?

Node.js is an open-source, cross-platform runtime environment for developing server-side Web applications.  Developers can write new modules in JavaScript. The runtime environment interprets JavaScript using Google's V8 JavaScript engine.

"One Ring to rule them all"

HOW?

HOW?

all extreme "Like demands discipline." programming and dedication crafts,

HOW?

"Like all crafts,

programming demands extreme dedication and discipline ."

"May the Force be with you."

Let's meet our actors...

Welcome

Joe

Welcome

Joe

Angel eyes

Welcome

Joe

Angel eyes

Paco

The good :-)

don't worry, evil doesn't have a chance!

The good / loose typing

    Variables are declared without a type, using the keyword 'var',  and their type is determined internally
    There is no type checking like in strong typed languages

var a = 3;    //number
var b = '4';  //string
var c = true; //boolean
var arr = [];  //array
var obj = {};  //object

//Invalid declarations:
number a = 3;
string b ='4';

The good / loose typing

string

number

boolean

Object
function

Array

Date

RegEx
 

(primitive types)

There are a few simple JavaScript Types:

(types of objects)

null
undefined

(special cases)

The good / functions

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

function statements

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

Javascript - the good, the bad, the ugly

By Tarun Sharma

Javascript - the good, the bad, the ugly

  • 894