js course

A crash course on building web sites and web applications with pure JavaScript

WHo Are We?


Yosef Dinerstein  - node.js and mongo hacker.
anode - an azure node.js continuous deployment platform.

Adi Ben Dayan - JavaScript hacker and front-end developer. on{X}.

Saar Yahalom - JavaScript, node.js hacker and front-end developer. ScrapBookanode.

What will be covered


Day 1
  • (Intro) Basic JS (1.5h)
  • Web UX Primer (1h)
  • IDE and Testing (Q&A 30min)

Day 2
  • Advanced JS (1.5h)
  • Web application development philosophy (30min)
  • MV* Development (1.5h)

What will not be covered


  • What is the best platform for you (node.js, WCF, MVC4, etc.)

  • What client side framework is superior. Do the homework decide what is best. 

  • JavaScript vs. TypeScript vs. Script#
    We are very blunt about this topic and will not go into the religious arguments.

Basic JS

A short introduction to JavaScript. Assumes you already know the syntax.

Javascript


A weakly typed dynamic language with three main types.

  • Objects
  • Arrays
  • Functions



Javascript is not a weaker form of c#


please, don't treat it as such
it's a different kind of beast

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.

  • 'Class members' are essentially public dictionary entries.

Basic object Defintion

    
    "use strict"
    
    var o = {};
    o['field 1'] = [1, 2, 3];
    
    o.field2 = "a";
    
    var o2 = {
       'field 1': [1, 2, 3]
       print: function() {
         console.log(arguments);
       }
    };
    

- The two forms are equivalent.
- Only use quotation marks for keys with spaces, prefer dot notation otherwise.
- Always use var.

- "use strict" for tighter enforcement.

let's see it in action

Array === list

var arr = [1, 2, 3, new Date(), 'wtf?'];


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 = [];
a[3] = 1;
console.log(a[0]); // undefined

- Get familiar with: push, pop, shift, unshift, splice and slice.

Functions are first class citizens


Functions can be stored inside variables and can be returned from other functions;

  • Function serve more roles than just execution units.
  • They define scope.
  • They define constructors.

function add(a,b) {
  return a+b;
} // no semicolon in this case
var add = function(a,b) { // anonymous like function
  return a+b;
}; // var always followed by a semicolon

Functions as a scope unit

// global scope
var a = 1;

function someFunc() {
  // someFunc scope
  var a = 2; // hides the outside variable
}

Functions can be used for local scoping

// a generator example
var adderGenerator = function(increment) {
  return function(num) { return num + increment; };
}


JavaScript can play most of the functional programming games: currying, generators, compositions, etc ...

Constructor FUNCTIONS

function MyClass() {
  // initialize the instance
  this.age = 15;
  this.name = 'bill';
}

var myInstance = new MyClass(); 
  • Sets the object prototype
  • The convention is to Capitalize constructor names.
  • The return value will be a new instance.
  • More about the new keyword on day 2.

Execution Contex


Scopes

scope - simply put is the environment where variable are contained.

scope chain - the current scope plus all parent scopes.
 
Outside of a function body the scope is the global scope, in the browser this usually means 'window'.

var a = 'I am on the global scope";

b = 'look ma no var'; // on the global scope as well (bad practice)

Functions as scopes

var getCustomer = function(id, onReady) {
  // promise is only known in the function scope
  var promise = $.get('/customers/' + id);
  // the customer object refers to the local function scope
  // this lets keep the customer object clean as possible
  var customer = {
    id: id,
    isReady: function() { return promise.isResolved(); }
  };

  promise.done(function(data) {
    var o = JSON.parse(data);

    for(var key in data) {
      customer[key] = o[key];
    }

    onReady(customer);
    // remove reference to the promise object
    customer.isReady = function() { return true; };
promise = null; }); return customer; }

Self INVOKING functions 

In many cases you don't want to litter the global scope.

The usual practice: 'self invoking functions'

// --- global scope ---
(function() { 
  // --- private scope ---
  function myHiddenVoodoo() { ... }
  var local = 1;

  var myAmazingClass = { 
    magic: function() { return myHiddenVoodoo() + local; },
... } this.Amazing = myAmazingClass; // gives access to the inner scope }).call(this);

what is this  ?

Well it depends ... this points to the current context.

In JavaScript you can control the current context, and the context is not 'bound' to the object.
A terrible design decision! 
You  will trip on it sooner or later so be wary about using this.
var name = 'bill';

function sayHello() {
  console.log('hello' + this.name);
}

sayHello(); // this will be the global context
sayHello.call({ name: 'john' }); // john
sayHello.apply({ name: 'jack' }); // jack

How to avoid shifting context bugs

var dataModule = {
  limit: 5,
  get: function(cb) {
    var self = this; // get a hold of the 'right' this
    $.get('/records').done(function(data) {
      // this is pointing to the ajax request object
      var records = JSON.parse(data);
      records.splice(self.limit);
      return cb(records);
    });
  }
};

Resources


Recommended books
  • JavaScript the good parts
  • Secrets of the JavaScript Ninja

Web UX Primer

  • Separation of concerns HTML, CSS, JS.
  • Loading sequence of a web page.
  • CSS (classes vs. ids)
  • Style tag vs. classes
  • Multiple browsers support
  • jQuery
  • Advanced CSS

Separation of Concerns

Web sites are built off HTML, CSS and JS files.

HTML
Semantic structure:
  - sections, lists, header, footer, forms.
  - static text

CSS
Skin and behavioral hints

JavaScript
Logic, Data (Models and Controllers)

Web Page Loading Sequence

Css - Classes vs. IDs

Style tags

Act as embedded CSS files.

If you don't have to don't use them


Multiple browser support


Different browsers support different sets of capabilities.
Today the situation is much improved IE10, Chrome and FF all support most of the html5 spec and a few drafts as well.

What about ie8 and ie9?

In order to cope with older browsers use polyfills.
Pollyfills are libraries that provide graceful fallback for missing features. Optimize for new browsers while making sure that older browsers still work.

jQuery

jQuery is used on virtually everywhere in the internet, and on most of the high profile sites.

 jQuery has tons of useful functions including:  
html element iteration, AJAX, promises, events, data store.

use it

If possible point directly to a CDN. It will increase the chance that the user already has cached.

Advanced Css

Use consistent semantic styles (button, link, headings)

Advanced CSS

Learn to use grids (twitter bootstrap for example)

this just an example use a grid system that is popular in your team

Advanced CSS

  • Reuse! when possible to avoid CSS bloat.
  • Use multiple classes per element
  • <div id="loginAlert" class="alert mid-size critical">
    You must log in first
    </div>

  • Minimize selector (don't be very specific)
  • Avoid IDs
  • Avoid height if possible
  • Avoid premature optimizations
  • Avoid redundancy
  • Choose a css officer

    We are engineers most of us suck at design.
    Accept it.


    • Choose the most artsy yet pedantic person to be in charge of the CSS files.
    • Work with a designer (a real designer not a PM) to define styles and and a solid UI language.
    • Have your CSS officer add and remove new styles
    • UX development is built with conventions and discipline not with a set of 'style cop' tools. 

    Playing it like the pros


    1. Take a look at this deck.
    2. Learn how to use less or sass
          
              @base: #f938ab;
      
      .box-shadow(@style, @c) when (iscolor(@c)) {
        box-shadow:         @style 
              @c;
        -webkit-box-shadow: @style 
              @c;
        -moz-box-shadow:    @style 
              @c;
      }
      .box-shadow(@style, @alpha: 50%) when (isnumber(@alpha)) {
        .box-shadow(@style, rgba(0, 0, 0, @alpha));
      }
      .box { 
        color: saturate(@base, 5%);
        border-color: lighten(@base, 30%);
        div { .box-shadow(0 0 5px, 30%) }
      }
          
    $blue: #3bbfce
    $margin: 16px
    
    .content-navigation
      border-color: $blue
      color: darken($blue, 9%)
    
    .border
      padding: $margin / 2
      margin: $margin / 2
      border-color: $blue

    Resources

    First day EXERCISE


    1. Install node.js 
    2. Create a basic webserver that can return files stored in a public directory.
    3. Extend the server to return the following json:
    [ 
     { "imageUrl": "img/default.png", description: "item 1" },
     { "imageUrl": "img/default.png", description: "item 2" },
    { "imageUrl": "img/default.png", description: "item 3" },
    { "imageUrl": "img/default.png", description: "item 4" },
    { "imageUrl": "img/default.png", description: "item 5" },
    { "imageUrl": "img/default.png", description: "item 6" },
    ]

         when accessing /data

    4. Create an index.html + mainViewModel.js to present  
         the items in a responsive list.
          

    A simple server in node.js

    var http = require('http');
    http.createServer(function(req, res) {
      console.log('[%s] %s', req.method, req.url);
      res.end('Yo node!');
    }).listen(3333);
    
    console.log('listening on port 3333');

    Advanced JavaScript



    • OOP in JS
    • Mixin
    • Modules
    • Async programming in JS
    • Promises pattern

    Yosef's evolution


    • Assembly x86
    • C
    • C++
      + Templates
       - Smart pointers
    • C#
    • JavaScript

    JavaScript


    • Nothing to do with Java
    • Not just a script
    • LANGUAGE
      - Small, but powerful
      - Imperative
      - Functional

    Cinderella


    • Beautiful behind a rough appearance.
    • Looks dirty on the first glance.
    • Underestimated.
    • Elegant.
    • Requires discipline.

    functions


                                    Other languages             JavaScript
                                    Methods                              Functions
                                    Classes                                 Functions
                                    Constructors                     Functions
                                    Modules                              Functions

    oop


    • Encapsulation
    • Polymorphism
    • Inheritance

    JavaScript oop

    • No classes
    • No declarations
    • Prototypal inheritance, but do we need really it?

    Pseudo Classical Inheritance


    function Constructor() {
      this.member = initializer;
    }
    
    Constructor.prototype.aMethod = function(a, b) {
      … do something
    };
    
    var newObject = new Constructor();
    

    Prototypes



    Prototypal inheritance


    var derived = Object.create(base);
    


    Functional style NO


        Constructors XXXX
       new             XXX
       prototype     XX
       this              X

    Functional STYLE YES


                   Functionality        Tool
                  Instantiation          Factory function
                  Encapsulation        Scope
                  Polymorphism        Augmentation


    example

    Zoo using functional inheritance


    MIXIN

    Instead of inheritance we extend pure objects.
    function extend(destination, source) {
      for (var k in source) {
        if (source.hasOwnProperty(k)) {
          destination[k] = source[k];
        }
      }
      return destination; 
    }
    
    var Module = {
      get: function() { ... },
      update: function() { ... },
    } var PersonModule = extend({ delete: function() {} }, Module);

    Modules

    Use self invoking functions to encapsulate the module
    You can read more about the JS module pattern here.
    // all module dependencies needs to be loaded before hand
    (function() {
      // get the namespace object
      var ns = this.ModuleNameSpace || {};
    
      // define the module  
      var module = {
         // define your module interface
         
      }
    
      // alter the global context
      ns.MyModule = module;
      this.ModuleNameSpace = ns;
    }).call(this);

    Modules - requirejs


    //Calling define with module ID, dependency array, and factory function
    define('myModule', ['dep1', 'dep2'], function (dep1, dep2) {
    
        //Define the module value by returning a value.
        return function () {};
    });

    Async Programming in JS


    • Callback is a function
    • Context is in a closure


    doSomething(param, function(err, result) {
     … continue upon completion
    });
    

    example

    serve file

    Async module


    • async
      - forEach
      - series
      - parallel
      - ...


    example foreach

    promises pattern

    Promises is a design pattern that helps deals for the nested callbacks mess.

    A promise is an object that represents an async operation and be easily be composed with other promises to create async operation chains that are not nested.

    jQuery contains an implementation of promises although it is not the best one.

    RSVP is a light weight implementation of promises

    A simple example

    var getJSON = function(url) {
      var promise = new RSVP.Promise();
    
      var client = new XMLHTTPRequest();
      client.open("GET", url);
      client.onreadystatechange = handler;
      client.responseType = "json";
      client.setRequestHeader("Accept", "application/json");
    
      function handler() {
        if (this.readyState === this.DONE) {
          if (this.status === 200) { promise.resolve(this.response); }
          else { promise.reject(this); }
        }
      };
    
      return promise;
    };
    getJSON("/post/1.json").then(function(post) {
      return getJSON(post.commentURL);
    }).then(function(comments) {
      // proceed with access to posts and comments
    }).then(null, function(error) {
      // handle errors in either of the two requests
    });

    Underscore.js

    Created by Jeremy Ashkenas another JavaScript ninja.
    It's a modern toolbox for JavaScript collections.
    The best part of it is that it uses a native implementation when it is available by the browser.

    _.each([1, 2, 3], function(num){ alert(num); });
    => alerts each number in turn...
    _.each({one : 1, two : 2, three : 3}, function(num, key){ alert(num); });
    => alerts each number in turn...
    _.map([1, 2, 3], function(num){ return num * 3; });
    => [3, 6, 9]
    _.map({one : 1, two : 2, three : 3}, function(num, key){ return num * 3; });
    => [3, 6, 9]

    Web application development philosophy



    How I believe web applications should be built using today's technologies.

    Imagine you are building a mobile app instead of a web app


    Things become very straight forward:

    1. Servers are used for plain data services.

    2. Client is responsible to render the data to the user and handle the application flows.

    MS pure options


  • Asp.Net
  • Asp.Net with MVC 3/4
  • Pure WCF services with a pure JS web application

  • ms supported options

    • node.js

    Which is the best for you?


    As long as your server only handles 'pure' data and is not rendering views or handling application flows use whatever you feel most comfortable with.

    There are very positive reviews on MVC 3/4
    I would start with that if you are heading toward the pure MS solution.

    We had great success with node.js but it is not for everyone.

    Scrapbook as an example


    Backend
    Pure WCF 'Restful' services that return JSON.
    Backend was responsible for authentication + CRUD using REST API.

    Frontend (Web application)
    Pure JavaScript sight using jQuery and a custom MVVM approach.

    Advantages


    • Backend design is simplified and is focused on the data services.

    • Backend services can serve multiple clients with no modification (web, mobile, mobile web, desktop).

    • Load on the web server is lowered significantly as application flows are done purely on the client side.

    • If done correctly helps make the website very responsive.

    MV* Development 

    js_course

    By Saar Yahalom

    js_course

    • 1,751