JavaScript – Types and grammar – this, objects and prototype



JavaScript – Types and grammar – this, objects and prototype

0 0


js-bootcamp


On Github pethel / js-bootcamp

JavaScript

Background

  • Part of Netscape(Mocha/LiveScript)
  • ECMAScript
  • "Interpreted" language
  • The language of the web
"JavaScript is a sword without a hilt."

Agenda

  • Types and grammar
  • this, objects and prototype
  • Functions, scope and closure

Types and grammar

Objects

In javascript everything is treated as objects except:

  • undefined
  • null
  • boolean
  • string
  • number
  • symbol(ES2015)
	console.log(typeof true);//boolean
	console.log(typeof 1);//number
	console.log(typeof undefined);//undefined
	console.log(typeof "Capra"); //string
	console.log(typeof null)//object???

null is technically a primitive. You can't add properties to it. What you see above is actually a bug. May be fixed in ECMAScript 6.

String is a primitive?

If string is a primitive. How can we do this?

	var name = "capra";
	console.log(name.length);//5

For a fraction of a section the primitive is coerced to an object.

Object wrappers

don't use wrapper objects for primitive types

var foo = new String('Hello world'); // Written by Java developer :)
console.log(typeof foo); // object
var myValue = new Boolean(false);
if(!myValue) {
   // the intention
} else {
   console.log('Ooooops');
}

Equality

  • Equality(==) allows coercion, identity(===) does not.
  • The Identity operator can never be slower.
	// Equality operator might surprise you
	'' == '0'           // false
	0 == ''             // true
	0 == '0'            // true

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

These rules are not well understood by all developers so always use the Identity operator when possible.

Conditionals

Conditionals checks for thruty or falsy values.

if({}) {
   console.log('objects are truthy')
}

|| and && return values

var foo = null || 'someString'; // foo === 'someString'
var bar = true && 'someString'; // bar === 'someString'

this, objects and prototype

Creating objects

  • Object Literal
  • Object constructor
  • Object.create
	//Object Literal
	var peter = {
	   name: "Peter",
	   shoeSize: 43
	}

	//Object constructor
	var morten = new Object();
	morten.name = "Morten";
	morten.shoeSize = null;

	//Object.create
	var gustav = Object.create(Object.prototype);
	gustav.name = "Gustav";
	gustav.shoeSize = 45;

Which one to use?

Use the Object literal or Object.create.

  • Less text (we save bandwidth)
  • Faster
  • Safer

Constructor functions

	function Person(firstname, lastname){
	   this.firstname = firstname;
	   this.lastname = lastname;
	}

	var peter = new Person("Peter", "Hellstrand");
	console.log(typeof Person);//function
	console.log(typeof peter);//object

Properties

Can be primitives or objects and accessed with dot or square bracket notation.

var goat =  {
   name: "Capra",
   makeSound : function(){
      return "Baaahhh";
   }
};
goat.numberOfLegs = 4;
goat["eat"] = function() {
   return "nam nam";
}

console.log(goat.name);//Capra
console.log(goat["name"]);//Capra
console.log(goat.makeSound());//Baaahhh
console.log(goat["makeSound"]());//Baaahhh
console.log(goat["numberOfLegs"]);//4
console.log(goat.eat());//nam nam

The Global Object

  • Properties like undefined, Infinity, and NaN
  • Functions like isNan(), parseInt() and eval()
  • Constructor functions like Date(), String and Object
  • Object like Math and JSON

The Window object

In a browser environment the "window" is exactly the same thing as the global object.

var theGlobal = this;
console.log(theGlobal === window);//true

Why is this bad?

function someName() {
   var b = 3;
   a = 2;
   return a + b;
}

The variable declared without "var" will become a property of the global object.

What is the "this" keyword?

"this" is not a reference to function itself or to the lexical scope.

What is printed?

var myObj = {
   value: 1,
   thisTest: function() {
      console.log(this.value); // ?
   }
};
var myOtherObj = {
   value: 2,
   thisTest: myObj.thisTest
};

console.log(myOtherObj.thisTest());//2

Determining this

new binding

If the function is called with the new keyword, then this is the newly created object.

function Bar() {
   this.value = 1;
}

var foo = new Bar();
console.log(foo.value);// 1

Explicit binding

If the function is called with call or apply this is the explicitly specified object.

function bar() {
   console.log(this.value);
}

var foo = {
   value: 9
};

bar.call(foo); //9

Implicit binding

If the function is called from within a context this is the context object.

function bar() {
   return this.value;
}

var foo = {
  value: 9,
  bar: bar
};

foo.bar();

Default binding

this will be the global object if not in strict mode

value = 2;
function foo() {
   console.log(this.value); // 2 (would be undefined in sctrict mode)
}

Prototype

  • All functions has a prototype
  • Shared between all instances created with the "new" keyword
  • Used to share variables and functions
function Goat(name, number) {
  this.name = name;
  this.number = number;
}

Goat.prototype.numberOfLegs = 4;
Goat.prototype.makeSound = function () {
   console.log("Bahh");
}

var goat1 = new Goat("Goat1", 1);
var goat2 = new Goat("Goat2", 2);

goat1.makeSound();//Bahh
goat2.makeSound();//Bahh

console.log(goat1.numberOfLegs);//4
console.log(goat2.numberOfLegs);//4

Why Prototype?

  • Faster object creation
  • Less memory

Functions, scope and closure

Functions

	/*Function decleration*/
	function A(){};

	/*Function expression*/
	var B = function(){}

	/*Namned function expression*/
	var C = function foo(){}

	/*Function constructor, as bad as eval()*/
	var D = new Function("....");

	/*Self invoking function expression*/
	(function(){})();

Functions are first class objects

  • Store them in variables
  • Pass them as arguments to other functions
  • Create new functions during the execution of a program
  • Inherits from Object
  • Constructors when invoked with new keyword

Function scope

Java (block scope)
public void foo() {
   if(true) {
      int a = 10;
   }
   System.out.println(a);//Error
}
JavaScript (function scope)
function foo() {
   if(true) {
      var a = 10;
   }
   console.log(a);//10
}

Function arguments

The arguments object is a local variable available within all functions.

function foo(a, b) {
   console.log(a); // Hello
   console.log(b); // undefined
}
test("Hello");
function bar() {
   for(var i = 0; i < arguments.length; i++) {
      console.log(arguments[i]); // 1,2,3 and 4
   }
}

Hoisting

Because variable declarations are processed before any code is executed, declaring a variable anywhere in the code is equivalent to declaring it at the top.

Original code:

function hoist() {
   var a = 2;
   for(var i = 0; i < 10; i++ ){}
   var b = 3;
}

Interpreted as:

function hoist() {
   var a, i, b;
   a = 2;
   for(i = 0; i < 10; i++ ){}
   b = 3;
}

Function Hoisting

Function declarations are hoisted.
Original code:
sayHello();//Hi!

function sayHello() {
   console.log("Hi!");
}
Interpreted as:
function sayHello() {
   console.log("Hi!");
}
sayHello();//Hi!

Function Hoisting

Function expression are not hoisted.
Original code:
sayHello();//Error

var sayHell = function() {
   console.log("Hi!");
}
Interpreted as:
var sayHello;
sayHello();//Error

sayHell = function() {
   console.log("Hi!");
}

Closure

"A closure is an expression (typically a function) that can have free variables together with an environment that binds those variables."

  • A closure is a function defined within another scope that has access to all the variables within the outer scope
  • It keeps state
  • Accessing variables outside of your immediate scope creates a closure
function getInnerFunction() {
   var counter = 0;
   return function() {
      return counter++;
   }
}

var theInnerFunction = getInnerFunction();
console.log(theInnerFunction());//0
console.log(theInnerFunction());//1
JavaScript