JavaScript FUNdamentals: The Powerful and Misunderstood Language of The Web - JavaScript and Node FUNdamentals: A Collection of Essential Basics (2014)

JavaScript and Node FUNdamentals: A Collection of Essential Basics (2014)

1. JavaScript FUNdamentals: The Powerful and Misunderstood Language of The Web

1.1 Expressiveness

Programming languages like BASIC, Python, C has boring machine-like nature which requires developers to write extra code that’s not directly related to the solution itself. Think about line numbers in BASIC or interfaces, classes and patterns in Java.

On the other hand JavaScript inherits the best traits of pure mathematics, LISP, C# which lead to a great deal of expressiveness (and fun!).

More about Expressive Power in this post: What does “expressive” mean when referring to programming languages?

The quintessential Hello World example in Java (remember, Java is to JavaScript is what ham to a hamster):

1 public class HelloWorld {

2 public static void main(String[] args) {

3 System.out.println("Hello World");

4 }

5 }

The same example in JavaScript:

1 console.log('Hello World')

or from within an HTML page:

1 <script>

2 document.write('Hello World')

3 </script>

JavaScript allows programmers to focus on the solution/problem rather that to jump through hoops and API docs.

1.2 Loose Typing

Automatic type casting works well most of the times. It a great feature that saves a lot of time and mental energy! There’re only a few primitives types:

1. String

2. Number (both integer and real)

3. Boolean

4. Undefined

5. Null

Everything else is an object, i.e., mutable keyed collections. Read Stackoverflow on What does immutable mean?

Also, in JavaScript there are String, Number and Boolean objects which contain helpers for the primitives:

1 'a' === new String('a') //false

but

1 'a' === new String('a').toString() //true

or

1 'a' == new String('a') //true

By the way, == performs automatic type casting while === not.

1.3 Object Literal Notation

Object notation is super readable and compact:

1 var obj = {

2 color: "green",

3 type: "suv",

4 owner: {

5 ...

6 }

7 }

Remember that functions are objects?

1 var obj = function () {

2 this.color: "green",

3 this.type: "suv",

4 this.owner: {

5 ...

6 }

7 }

1.4 Functions

Functions are first-class citizens, and we treat them as variables, because they are objects! Yes, functions can even have properties/attributes.

1.4.1 Create a Function

1 var f = function f () {

2 console.log('Hi');

3 return true;

4 }

or

1 function f () {

2 console.log('Hi');

3 return true;

4 }

Function with a property (remember functions are just object that can be invoked, i.e. initialized):

1 var f = function () {console.log('Boo');}

2 f.boo = 1;

3 f(); //outputs Boo

4 console.log(f.boo); //outputs 1

Note: the return keyword is optional. In case its omitted the function will return undefined upon invocation.

1.4.2 Pass Functions as Params

1 var convertNum = function (num) {

2 return num + 10;

3 }

4

5 var processNum = function (num, fn) {

6 return fn(num);

7 }

8

9 processNum(10, convertNum);

1.4.3 Invocation vs. Expression

Function definition:

1 function f () {};

Invocation:

1 f();

Expression (because it resolve to some value which could be a number, a string, an object or a boolean):

1 function f() {return false;}

2 f();

Statement:

1 function f(a) {console.log(a);}

1.5 Arrays

Arrays are also objects which have some special methods inherited from Array.prototype global object. Nevertheless, JavaScript Arrays are not real arrays. Instead, they are objects with unique integer (usually 0-based) keys.

1 var arr = [];

2 var arr2 = [1, "Hi", {a:2}, function () {console.log('boo');}];

3 var arr3 = new Array();

4 var arr4 = new Array(1,"Hi", {a:2}, function () {console.log('boo');});

1.6 Prototypal Nature

There are no classes in JavaScript because objects inherit directly from other objects which is called prototypal inheritance: There are a few types of inheritance patterns in JS:

· Classical

· Pseudo-classical

· Functional

Example of the functional inheritance pattern:

1 var user = function (ops) {

2 return { firstName: ops.name || 'John'

3 , lastName: ops.name || 'Doe'

4 , email: ops.email || 'test@test.com'

5 , name: function() { return this.firstName + this.lastName}

6 }

7 }

8

9 var agency = function(ops) {

10 ops = ops || {}

11 var agency = user(ops)

12 agency.customers = ops.customers || 0

13 agency.isAgency = true

14 return agency

15 }

1.7 Conventions

Most of these conventions (with semi-colons being an exception) are stylistic, and highly preferential and don’t impact the execution.

1.7.1 Semi-Colons

Optional semi-colons, except for two cases:

1. In for loop construction: for (var i=0; i++; i<n)

2. When a new line starts with parentheses, e.g., Immediately-Invoked Function Expression (IIFE): ;(function(){...}())

1.7.2 camelCase

cameCase, except for class names which are CapitalCamelCase, e.g.,

1 var MainView = Backbone.View.extend({...})

2 var mainView = new MainView()

1.7.3 Naming

_,$ are perfectly legitimate characters for the literals (jQuery and Underscore libraries use them a lot).

Private methods and attributes start with _ (does nothing by itself!).

1.7.4 Commas

Comma-first approach

1 var obj = { firstName: "John"

2 , lastName: "Smith"

3 , email: "johnsmith@gmail.com"

4 }

1.7.5 Indentation

Usually it’s either tab, 4 or 2 space indentation with their supporters’ camps being almost religiously split between the options.

1.7.6 White spaces

Usually, there is a space before and after =, +, { and } symbols. There is no space on invocation, e.g., arr.push(1);, but there’s a space when we define an anonymous function: function () {}.

1.8 No Modules

At least until ES6, everything is in the global scope, a.k.a. window and included via <script> tags. However, there are external libraries that allow for workarounds:

· CommonJS

· AMD and Require.js

Node.js uses CommonJS-like syntax and has build-in support for modules.

To hide your code from global scope, make private attributes/methods use closures and immediately-invoked function expressions (or IIFEs).

1.9 Immediately-Invoked Function Expressions (IIFEs)

1 (function () {

2 window.yourModule = {

3 ...

4 };

5 }());

This snippet show an example of a object with private attribute and method:

1 (function () {

2 window.boo = function() {

3 var _a = 1;

4 var inc = function () {

5 _a++;

6 console.log(_a);

7 return _a;

8 };

9 return {

10 increment: inc

11 };

12 }

13 }());

14 var b = window.boo();

15 b.increment();

Now try this:

1 b.increment();

2 b.increment();

3 b.increment();

1.10 Keyword “this”

Mutates/changes a lot (especially in jQuery)! Rule of thumb is to re-assign to a locally scoped variable before attempting to use this inside of a closure:

1 var app = this

2 $('a').click(function(e){

3 console.log(this) //most likely the event or the target anchor element

4 console.log(app) //that's what we want!

5 app.processData(e)

6 })

When in doubt: console.log!

1.11 Pitfalls

JS is the only language that programmers think they shouldn’t learn. Things like === vs. ==, global scope leakage, DOM, etc. might lead to problems down the road. This is why it’s important to understand the language or use something like CoffeeScript, that take a way most of the issues.

1.12 Further Learning

If you liked this articled and would like to explore JavaScript more, take a look at this amazing free resource: Eloquent JavaScript: A Modern Introduction to Programming.

Of course for more advanced JavaScript enthusiasts and pros, there’s my book Rapid Prototyping with JS and intensive programming school HackReactor, where I teach part-time.