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}.
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!
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.
- 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.
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)
Advanced CSS
<div id="loginAlert" class="alert mid-size critical">
You must log in first
</div>
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
- Take a look at this deck.
- 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
- Install node.js
- Create a basic webserver that can return files stored in a public directory.
- 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.
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
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.
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:
- Servers are used for plain data services.
- Client is responsible to render the data to the user and handle the application flows.
MS pure options
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.
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.
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