Javascript
- The most popular programming language in the world.
- The language for the web, for HTML, for servers, PCs, laptops, tablets, cell phones, and more.
- Very widely used, and growing, very common to use JavaScript to manipulate the HTML DOM.
- Developed by Brendan Eich at Netscape as a scripting language for Navigator 2
- Related to Java in name only
- JS Style guide by AirBNB- https://github.com/airbnb/javascript
Primitive Datatypes
-
Number
- 64-bit floating point, similar to Java double and Double
- No integer type
- Special values NaN (not a number) and Infinity
-
String
- Sequence of zero or more Unicode characters
- No separate character type (just strings of length 1)
- Literal strings using ' or " characters (must match)
-
Special values
- null and undefined
- typeof(null) = object; typeof(undefined)=undefined
- Boolean
- Two values: true and false
-
Empty strings, undefined, null and 0 are all treated as false
Variables
- No type specified, can be changed dynamically
- Variables with no value have undefined value
- Always use var, otherwise the variable is defined on the global scope
- It's a good practice to define variables at the beginning of a function
var pi = 3.14; // pi is a Number
var person = "John Doe"; // person is a string
var answer = 'Yes I am!'; // answer is a string
console.log(typeof answer); // string
answer = 10; // answer is now a number
console.log(typeof answer); // number
var a; // a is undefined
globalVariable = 'i am a global variable';
// one statement, many variables
var lastname = "Doe", age = 30, job = "carpenter";
var lastname; console.log(lastname); // still contains "Doe"
Object == DICTIONARY
- Every object in JS is basically a dictionary
-
Entries can be of any of the main types (object, array, function) or any of the basic types (String, Number, Date, RegExp)
-
Entries can be added dynamically at any time
- A function defines an object with method called "()"
function max(x, y) { if (x > y) return x; else return y; };
max.description = 'return the maximum';
console.log(max.description); // 'return the maximum'
console.log(max(1, 2)); // 2
Defining an object
- Everything is an object- string, array, number, function
-
Properties are values associated with objects
-
Methods are actions that objects can perform
-
objects are data (variables), with properties and methods
- Objects can be modified with new properties any time
var person = new Object(); person.firstname = "Ami"; person.lastname = "Turgman"; person.age = 37; person.eyescolor = 'brown';
var anotherPerson = { firstname: 'John', lastname: 'Doe' }; anotherPerson.age = 50; // dot notation anotherPerson['eyescolor'] = 'blue'; // key notation
console.log(person, anotherPerson);
A function member
var anotherPerson = {
firstname: 'John', lastname: 'Doe', getFullName: function () { return this.firstname + ' ' + this.lastname; } }; console.log(anotherPerson.getFullName()); // John Doe
-
this represents the current object the method is running on.
- In most cases, this points to the object which has the function as a property
-
this is resolved dynamically when the method is executed
- this can be changed explicitely using the call/apply object functions
console.log(anotherPerson.getFullName.call(person));
- The object person does not have the getFullName method
- We can invoke any function on any object
Array == List
- Arrays are just dynamic lists. They serve as a powerful container. Basic functionality of list, queue and stack.
- Prefer using the [ ] notation to the new Array() directive.
var a = [], b = new Array(); // both equivalent
a[0] = 0, a[1] = 1, a[3] = 3; console.log(a.join(',')); // 0,1,,3 b.push(1, 'a', null, undefined, true); console.log(b); // [1, "a", null, undefined, true]
- Array API: push, pop, shift, unshift, splice and slice
Functions
- Always returns a value
- undefined is used if returned value was not provided
-
Basic types passed by value, objects by reference
- Can have any number of parameters
- Caller can call the function with any number of arguments
- Missing arguments will have the value undefined
- Extra arguments will be ignored
function myFunc(a, b) {
console.log(a, b);
}
var result = myFunc(1, 2); // 1 2
console.log(result); // undefined
myFunc('a'); // a undefined
- myFunc is a named function and can be invoked by calling it
Functions returning function
- Functions can be returned from other functions and be stored in variables
function getAdder(sum) {
sum = sum || 0;
return function (num) {
sum += num;
return sum;
}
}
var adderFunc = getAdder(100);
console.log(adderFunc(1)); // 101
console.log(adderFunc(2)); // 103
console.log(adderFunc(3)); // 106
- The internal adder function is an anonymous function
- anonymous functions are usually used as callbacks
setTimeout(function(){ console.log('time expired'); }, 100);
- Even though the adder function is being called from outside of the getAdder() function, it still has access to the sum variable.
- this is called closure
Closures
- Inner functions have access to variables in the outer function.
- Accessing variables outside of your immediate lexical scope creates a closure.
- A closure is the local variables for a function- kept alive after the function has returned, or a closure is a stack-frame which is not deallocated when the function returns
function sayHello(name) {
var text = 'hello ' + name; return function () { console.log(text); } } var sayHelloFunc = sayHello('ami'); sayHelloFunc(); // hello ami
function say100() {
// Local variable that ends up within closure
var num = 100;
var logNum = function() { console.log(num); }
num++;
return logNum;
}
var logNumFunc = say100();
logNumFunc(); // 101
Closures- cont
- Be careful when passing references to objects
- You might get unexpected behavior when the objects values are changed
function foo(x) {
var tmp = 2; return function (y) { console.log(x.val + y + tmp); } } var obj = { val: 10 }; var bar = foo(obj); // bar is now a closure referencing obj. bar(3); // 15 obj.val = 20; bar(3); // 25
Self invoking functions
-
A function can be declared and execute itself
- (function(params) { function body } )(variables);
var u = { a: 1, b: 2 };
var v = { a: 3, b: 4 }; console.log(u, v); // {a: 1, b: 2} {a: 3, b: 4} (function (x, y) { var tempA = x.a, tempB = x.b; //local variables x.a = y.a; x.b = y.b; y.a = tempA; y.b = tempB; })(u, v); console.log(u, v); // {a: 3, b: 4} {a: 1, b: 2}
// This works because objects are passed by reference
Scope
- The environment where variable are contained
- Scope chain - the current scope plus all parent scopes
- A variable that was set in a function without defining it previously will be defined in the global scope
- Outside of a function body the scope is the global scope, in the browser this usually means 'window'
var externalVar = 'external';
function myFunc() { var myFuncVar = 'myFunc'; function internalFunction() { var internalVar = 'internal'; console.log(externalVar, myFuncVar, internalVar, globalVar); } globalVar = 'global'; internalFunction(); // external myFunc internal global } myFunc(); console.log(globalVar); // global console.log(myFuncVar); // myFuncVar is not defined console.log(internalVar); // internalVar is not defined
The arguments object
- The arguments object is an array-like object containing all the parameters that were passed to the function
- Used usually when there is a variable number of parameters that can be passed to a function
function sumAll() {
var total = 0; for (var i = 0; i < arguments.length; i++) total += sumAll.arguments[i]; return total; } console.log(sumAll(1, 2, 3, 4, 5)); // 15
Dynamically number of params
- It is a common design to send a single object with the parameters value
- Can be changed dynamically without changing the API
function doWebRequest(options) {
var scheme = options.scheme || 'http'; var port = options.port || 80; var url = scheme + '://' + options.host + ':' + port + options.path; console.log('calling', url); } doWebRequest({ host: 'microsoft.com', path: '/js' }); doWebRequest({ scheme: 'https', port: 441, host: 'microsoft.com', path: '/js' });
// calling http://microsoft.com:80/js // calling https://microsoft.com:441/js
Function as a class
- Using the new keyword to create an instance of a class
- The convention is to Capitalize constructor names
function Person(name, age) {
this.name = name; this.age = age; this.getDetails = function () { return this.name + ', ' + age; }; } var p1 = new Person('ami', 37); var p2 = new Person('guy', 28); console.log(p1.getDetails()); // ami, 37 console.log(p2.getDetails()); // guy, 28
Inheritance
-
No built-in inheritance
- Runtime Inheritance: Clone objects and add extra properties
- Some libraries provide all kind of 'inheritance-like' functionality
Flow control
- If... else
if (time < 10) {
x = "Good morning";
}
else if (time < 20) {
x = "Good day";
}
else {
x = "Good evening";
}
- Switch
var day = new Date().getDay();
switch (day) {
case 6:
x = "Today is Saturday";
break;
case 0:
x = "Today is Sunday";
break;
default:
x = "Looking forward to the Weekend";
}
Loops
- for
var numbers = [1, 2, 3], sum = 0;
for (var i = 0; i < numbers.length; i++) { sum += numbers[i]; } console.log(sum); // 6
-
for.. in (iterate through object keys)
var txt = "";
var person = { fname: "John", lname: "Doe", age: 25 };
for (var x in person) {
txt = txt + person[x];
}
console.log(txt); // JohnDoe25
- While
var i = 0, x = 0;
while (i < 5) { x = x + i; i++; }
Loops- break / continue
for (var i = 0; i <= 5; i++) { if (i == 3) continue; console.log(i); // 0, 2, 2, 4, 5 }
for (var i = 0; i <= 5; i++) { if (i == 3) break; console.log(i); // 0, 1, 2 }
Exceptions
- Errors will happen
- When the JavaScript engine is executing JavaScript code, different errors can occur:
- It can be syntax errors, typically coding errors or typos made by the programmer.
-
It can be misspelled or missing features in the language (maybe due to browser differences).
-
It can be errors due to wrong input, from a user, or from an Internet server.
- And, of course, it can be many other unforeseeable things.
Try.. Catch.. Throw
- Can throw any object as an error
function div(x, y) {
try {
if (!x && !y) throw 'please provide x and y';
if (y === 0) throw 'can not divide by 0';
console.log(x/y);
}
catch(err) {
console.log('error:', err);
}
}
div(10, 2); // 5
div(); // error: please provide x and y
div(10, 0); // error: can not divide by 0
Async Functions
- Calling an async function with a callback function that will be invoked once it has completed its work
function doWorkAndCallMeWhenDone(callback) {
console.log('starting work');
setTimeout(function () {
console.log('work completed, calling callback');
callback();
}, 1000);
}
var onCompleteHandler = function () {
console.log('work is completed, now i can proceed with
my next task');
};
doWorkAndCallMeWhenDone(onCompleteHandler);
Async error handling
- A common design is that a callback function will have an error object as its first parameter and then the returned values
- If there was an error during the async function work, it will invoke the callback with the error as its first value
- First thing the callback will do is to check if there was an error
function doWorkAndCallMeWhenDone(callback) {
console.log('starting work'); setTimeout(function () { console.log('work completed with error, notifying caller'); callback('some error occurred'); }, 1000); } doWorkAndCallMeWhenDone(function (err, result) { if (err) return console.error('error doing work:', err); console.log('work is completed, now i can proceed with next task'); });
Async function
- checking for errors and getting the result from the async call
function doWorkAndCallMeWhenDone(callback) {
console.log('starting work'); setTimeout(function () { console.log('work completed successfully, notifying caller'); callback(null, 'some result object'); }, 1000); } doWorkAndCallMeWhenDone(function (err, result) { if (err) return console.error('error doing work:', err); console.log('work is completed with result:', result); });
Christmas tree problem
- Look for the tree...
function async(x, cb) { cb(null, x + 1); } function executeAsyncSequence(cb) { async(0, function (err, res) { async(res, function (err, res) { async(res, function (err, res) { cb(null, res); }); }); }); } executeAsyncSequence(function (err, res) { console.log('result:', res); });
- There are libraries that makes this look sequentially
Checking parameters
- Sometimes you allow you async function to be called without providing parameters or a callback
- This is a common design
function asyncFun(param, cb) {
if (typeof param == 'function') cb = param;
cb = cb || function () {console.log('completed work');};
// do some async work
cb();
}
asyncFun('some value', function () {console.log('here!');});
asyncFun(function () { console.log('here!'); });
asyncFun();
Javascript
By Ami Turgman
Javascript
- 1,856