Andrei Pall

Linux Software Engineering

Learn JavaScript

JavaScript (JS) is a lightweight, interpreted, programming language with first-class functions. Most well-known as the scripting language for Web pages, many non-browser environments also use it, such as node.js and Apache CouchDB. JS is a prototype-based, multi-paradigm, dynamic scripting language, supporting object-oriented, imperative, and functional programming styles.

Variables, Types and Scope

var orderId;
console.log(orderId);
undefined
var orderId = 9001;
console.log(orderId);
9001
var orderId = 9001;
console.log(typeof orderId);
number
var orderId = ORD-9001;
console.log(typeof orderId);
string
var isActive = true;
console.log(typeof isActive);
boolean
var isActive;
console.log(typeof isActive);
undefined
var order = {
  orderId: 9001,
  isActive: true
};
console.log(typeof order);
object
var cancelledOrders = [9001, 9002,
9003];
console.log(typeof cancelledOrders);
object
var order = null;
console.log(typeof order);
object
function cancelOrder(orderId) {
};
console.log(typeof cancelOrder);
function

Function Fundamentals

function printOrder() {
  console.log(Printing order.);
};
printOrder();
Printing order.
function calcTotalPrice(quantity, price) {
  console.log('Total price: ' + (quantity * price));
};
calcTotalPrice(2, 4.00);
Total price: 8
function calcTotalPrice(quantity, price, currency)
{
  console.log(currency);
};
calcTotalPrice(2, 4.00);
undefined
function getOrder() {
// nothing returned
};
var order = getOrder();
console.log(order);
undefined

If and Switch Statements

var orderType = 'business';
var shipMethod;
if (orderType == 'business')
  shipMethod = 'FedEx';
else if (orderType == 'personal')
  shipMethod = 'UPS Ground';
else
  shipMethod = 'USPS';
console.log(shipMethod);
FedEx
var orderType = 'business';
var shipMethod;
switch (orderType) {
  case 'business':
    shipMethod = 'FedEx';
    // break;
  case 'personal':
    shipMethod = 'UPS Ground';
    break;
  default:
  shipMethod = 'USPS';
}
console.log(shipMethod);
var orderTotal = 99.99;
var discount;
switch (true) {
  case orderTotal >= 50 && orderTotal < 75:
    discount = 10;
    break;
  case orderTotal >= 75 && orderTotal < 100:
    discount = 20;
    break;
  case orderTotal >= 100:
    discount = 30;
    break;
  default:
    discount = 0;
}
console.log(discount);

while and do...while Statements

var lineItemCount = 3;
var currentItem = 0;
while (currentItem < lineItemCount) {
  console.log("item: " + currentItem);
  currentItem++;
}
var lineItemCount = 3;
var currentItem = 0;
do {
  console.log("item: " + currentItem);
  currentItem++;
} while (currentItem < lineItemCount);

for and for...in

var lineItemCount = 5;
for (var i = 0; i < lineItemCount; i++) {
  console.log(i);
  if (i == 1)
    break;
}
0
1
var lineItemCount = 5;
for (var i = 0; i < lineItemCount; i++) {
  if (i == 1)
    continue;
    console.log(i);
}
0
2
3
4
var lineItem = {
  product: "Widget 1",
  quantity: 4,
  price: 9.50
};
for (var field in lineItem)
  console.log(field + " : " + lineItem[field]);
product : Widget 1
quantity : 4
price : 9.50

Hoisting

Hoisted variables are initialized to undefined.

console.log(productId);
ReferenceError:
productId is not defined
console.log(productId);
var productId = '9000';
undefined
var total = price * quantity;
var price = 3.00;
var quantity = 5;
console.log(total);
NaN
showProduct();
function showProduct() {
  console.log('Showing a Product');
}
Showing a Product
showProduct();
var showProduct = function () {
  console.log('Showing a Product');
}
TypeError: showProduct is not a function
var showProduct = function () {
  console.log('Showing a Product');
}
showProduct();
Showing a Product
showProduct();
function showProduct() {
  console.log('Showing a Product');
}
Showing a Product

Numbers

var count;
var price = 5.00;
console.log(price / count);
NaN
console.log(typeof NaN);
number
var n = NaN;
if (isNaN(n))
  console.log('NaN!');
NaN!

Strings

var productType = 'Hardware';
console.log(productType.toLowerCase());
hardware

Boolean Values

var isSpecial = true;
if (isSpecial)
  console.log("It's true!");
Its true!

undefined and null

var productId;
console.log(typeof productId);
undefined
var productId = null;
console.log(typeof productId);
object
console.log(typeof null);
object
console.log(undefined == null);
true
console.log(undefined === null);
false

Global Scope

PRD-2000
PRD-2000
console.log(this === window);
true

Function Scope

var description = 'original product';
function updateProduct() {
  var description = 'updated product';
  var updateProductId = function () {
    console.log(description);
  }
}
updateProductId();
updateProduct();
updated product

Block Scope

'use strict';
try {
  throw 123;
}
catch (e) {
  console.log(e);
}
123
'use strict';
console.log(insideCatch);
try {
  throw 123;
}
catch (e) {
  var insideCatch = 'insideCatch';
  console.log(e);
}
undefined
123

Reference Type Examples

var blog = {
  name: 'Ski Utah'
};
var updatedBlog = blog;
console.log(updatedBlog.name);
Ski Utah
var blog = {
  name: 'Ski Utah'
};
function changeBlogName(localBlog) {
  localBlog.name = 'no name';
}
changeBlogName(blog);
console.log(blog.name);
no name

Array Fundamentals

var entries = new Array('Trains', 'Plains', 'Automobiles');
console.log(entries instanceof Array);
true
var entries = new Array('Trains', 42, true);
console.log(entries instanceof Array);
true
var entries = ['Trains', 'Plains', 'Automobiles'];
console.log(entries[3]);
undefined
var ratings = [];
ratings.push(5);
ratings.push(2, 4);
console.log(ratings.pop());
4

Date Fundamentals

var dt = new Date();
console.log(dt);
Fri Sep 25 2016 11:20:11 GMT-0700 (Pacific Daylight Time)
var dt = new Date();
console.log(dt.getFullYear());
2016

Regular Expressions

var blogText = "Sam I Am";
var pattern = /am/g;
console.log(pattern.test(blogText));
true
var blogText = "Sam I Am";
var pattern = /m/g;
var result = pattern.exec(blogText);
console.log(result);
["m", index: 2, input: "Sam I Am"]
var blogText = "Sam I Am";
var pattern = /m/g;
var result = blogText.match(pattern);
console.log(result);
["m", "m"]

Simple Objects and JSON

var project = new Object();
project.name = 'Project Phoenix';
console.log(project.name);
Project Phoenix
var project = new Object();
project.name = 'Project Phoenix';
project.securityLevel = 15;
project.updateDueDate = function () {
  return true;
};
console.log(project.updateDueDate());
true
var project = {};
project.name = 'Project Phoenix';
console.log(project.name);
Project Phoenix
var project = {
  name: 'Project Phoenix',
  securityLevel: 15,
  updateDueDate: function () {
    return true;
  }
};
console.log(project.name);
Project Phoenix
var project = {
  tasks: [
    {
      taskName: 'first'
    },
    {
      taskName: 'second'
    }
  ]
};
console.log(project.tasks[1].taskName);
second

Prototypes

Every JavaScript Object has a prototype property. However, we don’t always have access to it. The prototype property is simply an object.

var project = anyObject;
project.someFunction();

How does JavaScript locate / resolve someFunction?

  • project.someFunction()
  • project.prototype.someFunction()
  • project.prototype.prototype.someFunction()
  • project.prototype.prototype.prototype.someFunction()
  • etc.

Object.create() and Prototypes

var project = {
  securityLevel: 2
};
var secretProject = Object.create(project);
console.log(secretProject.__proto__ === Object.prototype);
false
var project = {
  securityLevel: 2
};
var secretProject = Object.create(project);
console.log(secretProject.__proto__.__proto__ === Object.prototype);
true
var task = { };
Object.defineProperty(task, 'text', {
  value: 'Get this job done!'
});
console.log(task.text);
Get this job done!
'use strict';
var task = {
  dueDate: '1/15/16'
};
Object.defineProperty(task, 'dueDate', {
  get: function () {
    return this.dueDate;
  },
  set: function (newValue) {
    this.dueDate = newValue;
  }
});
task.dueDate = '2/2/16';
console.log(task.dueDate);
2/6/16

Miscellaneous Object Functions

'use strict';
var project = {
  name: 'Top Secret Project',
  dueDate: '1/1/2016'
};
console.log(project.hasOwnProperty('name'));
true
'use strict';
var project = {
  name: 'Top Secret Project',
  dueDate: '1/1/2016'
};
console.log(project.hasOwnProperty('toString'));
false
'use strict';
var project = {
  name: 'Top Secret Project',
  dueDate: '1/1/2016'
};
console.log(project.__proto__.hasOwnProperty('toString'));
true
'use strict';
var project = {
  name: 'Top Secret Project',
  dueDate: '1/1/2016'
};
console.log(Object.prototype.isPrototypeOf(project));
true
var project = {
  securityLevel: 2
};
var secretProject = Object.create(project);
console.log(project.isPrototypeOf(secretProject));
true
var project = {
  securityLevel: 2
};
var secretProject = Object.create(project);
console.log(Object.prototype.isPrototypeOf(secretProject));
true

Naming Function Expressions

var hireEmployee = function (name) {
};
console.log(typeof hireEmployee);
function
var hireEmployee = function (name) {
  throw ('Error');
};
hireEmployee('JJ');
Uncaught Error - hireEmployee

Constructor Functions

console.log(typeof Object);
function
var Employee = function (name) {
  this.name = name;
};
var newEmployee = new Employee('JJ');
console.log(typeof newEmployee);
object
var Employee = function (name) {
  this.name = name;
};
var e1 = new Employee('JJ');
var e2 = new Employee('JV');
console.log(e1.__proto__ === e2.__proto__);
true
var Employee = function (name) {
  this.name = name;
  this.giveRaise = function () {
  };
};
var e1 = new Employee('JJ');
var e2 = new Employee('JV');
console.log(e1.giveRaise === e2.giveRaise);
false
console.log(typeof this);
object
console.log(this === window);
true
var name = 'Jeff';
console.log(this.name);
Jeff
var employee = {
  name: 'Jeff',
  updateSalary: function () {
    console.log(this);
  }
};
employee.updateSalary();
Object {name: "Jeff"}
var employee = {
  name: 'Jeff',
  updateSalary: function () {
    var fn = function () {
      console.log(this);
    };
    fn();
  }
};
employee.updateSalary();
Window {...}
var Address = function (line1) {
  this.line1 = line1;
};
Address.prototype.updateZipCode = function () {
  console.log(this);
};
var addr = new Address('123 State St.');
addr.updateZipCode();
Address {line1: "123 State St."}

Using call() and apply()

var updateZipCode = function () {
  console.log(this);
};
updateZipCode.call({});
Object {}
var updateZipCode = function () {
  console.log(this);
};
updateZipCode.call({ zip: '11787'});
Object {zip: "11787"}
var updateZipCode = function (newZip, country) {
  console.log(newZip + ' ' + country);
};
var zipCode = {
  zip: '11787'
};
updateZipCode.call(zipCode, '11888', 'us');
11888 us
var updateZipCode = function (newZip, country) {
  console.log(newZip + ' ' + country);
};
var zipCode = {
  zip: '11787'
};
updateZipCode.apply(zipCode, ['11888', 'us']);
11888 us
var updateZipCode = function (newZip, country) {
  console.log(newZip + ' ' + country);
};
var zipCode = {
  zip: '11787'
};
updateZipCode.apply(zipCode, '11888', 'us');
Uncaught TypeError: Function.prototype.apply: Arguments list has wrong type

Closures

var salaryUpdater = function (salary) {
  var currentSalary = salary;
  var generator = function () {
    currentSalary = currentSalary * 2;
    return currentSalary;
  };
  return generator;
};
var updateFn = salaryUpdater(50000);
console.log(updateFn());
100000
var salaryUpdater = function (salary) {
  var currentSalary = salary;
  var generator = function () {
    currentSalary += 10000;
    return currentSalary;
  };
  return generator;
};
var updateFn = salaryUpdater(50000);
updateFn();
console.log(updateFn());
70000

IIFEs

Immediately Invoked Function Expressions

(function () {
  console.log('Executed!');
})();
Executed!
var app = {};
(function (ns) {
  ns.name = 'None';
})(app);
console.log(app.name);
None

Recursion

var orgChart = {
name: 'Michael', subordinates: [
    {
      name: 'Andy', subordinates: [
      {
        name: 'Dwight', subordinates: []
      },
      {
        name: 'Kevin', subordinates: []
      }
      ]
    }
  ]
};
var fn = function (topEmployee) {
console.log(topEmployee.name);
for (var i = 0; i < topEmployee.subordinates.length; i++)
  fn(topEmployee.subordinates[i]);
};
fn(orgChart);
Michael
Andy
Dwight
Kevin

Error Handling

try {
  throw new Error('Custom Error');
}
catch (e) {
  console.log(e.name + ' - ' + e.message);
}
Error - Custom Error
try {
  throw new Error('Custom Error');
}
catch (e) {
  console.log(e.name + ' - ' + e.message);
}
finally {
  console.log('Finally done.');
}
Error - Custom Error
Finally done.