JavaScript from Hell

There's still time for you to give up

Maurício Linhares / @mauriciojr

Equality in JavaScript?


var jose = {"nome":"José"};
var maria =  {"nome":"José"};
jose == maria
> false
jose.nome == maria.nome
> true
1 == "1"
> true
1 == 1
> true
1 === "1"
> false
1 === 1
> true

new will bite you


function Person(name) {
	this.name = name;
}

Person.prototype.hello = function() {
	return "Hello " + this.name;
}

var me = new Person("Joe");
me.hello()
> "Hello Joe"

var other = Person("Mark");
other.hello()
> TypeError: Cannot call method 'hello' of undefined

hack to fix the forgot to use new issue


function Person(name) {
	if ( !(this instanceof Person) )
	      return new Person(name);

	this.name = name;
}

Person.prototype.hello = function() {
	return "Hello " + this.name;
}

var other = Person("Mark");
other.hello()
> "Hello Mark"

from vars global vars in a single step


name = "Mario";
var otherName = "Luigi";
(function updateName(){
	var otherName = "Yoshi";
	name = "Bowser";
	var princess = "Peach";
	drunk = "Toad";
}());

console.log(name);
> Bowser
console.log(drunk);
> Toad
console.log(otherName);
> Luigi
console.log(princess);
> ReferenceError: princess is not defined

with never again


var obj = {"name":"Rex Colt"};
with(obj) {
  surname = name.split(" ")[1];
}

console.log(obj["surname"]);
> undefined
console.log(surname);
> Colt

dynamic typing is cool, isn't it?


[] + []
> ""
[] + {}
> [object Object]
{} + []
> 0
{} + {}
> NaN

but ruby does it the same way, doesn't it?


[] + []
> []
[] + {}
> TypeError: no implicit conversion of Hash into Array
{} + []
> NoMethodError: undefined method `+' for {}:Hash

callback hell


function myAction(result) {
	console.log("result is " + result);
}

client.connect(function(err) {
	if(err) {
		return console.error('could not connect to postgres', err);
	}
	client.query("BEGIN TRANSACTION", function(err, result) {
		if(err) {
			return console.error('error running query', err);
		}
		client.query("SELECT 0", function(err, result) {
			if(err) {
				return console.error('error running query', err);
			}
			client.query("COMMIT", function(err, result) {
				if(err) {
					return console.error('error running query', err);
				}
				myAction(result);
			});
		});
});

what about promises?


val handler = new DatabaseConnectionHandler( ... )
val result = handler.connect
  .map( parameters => handler )
  .flatMap( connection => connection.sendQuery("BEGIN TRANSACTION") )
  .flatMap( query => handler.sendQuery("SELECT 0") )
  .flatMap( query =>
	  handler.sendQuery("COMMIT")
		  .map( value => query.rows(0) )
  )

scope? what's that?


var items = [1, 2, 3];
for ( var x = 0; x < items.length; x++ ) {
	var item = items[x];
}

console.log(item);
> 3

only functions create a new scope


var items = [1, 2, 3];
items.forEach( function(item) {
	console.log("item é " + item);
} );

console.log(item);
> ReferenceError: item is not defined

careful with how you define stuff - before



myFunction();

function myFunction() {
	console.log("function called");
}

var myFunction = function () {
	console.log("variable called");
}

> "function called"

careful with how you define stuff - after



function myFunction() {
	console.log("function called");
}

var myFunction = function () {
	console.log("variable called");
}

myFunction();

> "variable called"

what now?



( function myFunction() {
	console.log("function called");
} );

myFunction();

> ReferenceError: myFunction is not defined

what else?

  • inheritance
  • this
  • DOM manipulation
  • debugging

is there hope for JavaScript?

Yes!

But it's important to understand the problems, alternatives and what other people, languages and communities are doing.

THE END

By Maurício Linhares / made with reveal.js