ict.ken.be

Delivering solid user friendly software solutions since the dawn of time.

Visual Studio Extention that shows the shortcut keys  

Categories: Shortcuts Visual Studio

IntelliCommand helps to remember shortcut keys. This extension is supported for Visual Studio 2010/2012 Professional and higher.It shows the help windows with all possible combinations when you press Ctrl or Shift or Alt or their combinations (hold it for about 2 seconds to see this window). Also it shows the list of possible combination when you press first combination of chord shortcut keys, like Ctrl+K, Ctrl+C (this combination comments selected text in editor).

Introduction to TypeScript - Notes 

Categories: Javascript Notes
Introduction to TypeScript
Anders Hejlsberg
There is a lot of fuss about 'the language' TypeScript. I personally think it is because most people did not have a clear look at it for themselves and already decided that just because it is from Microsoft it must not be good. Anyway, since I strongly believe that more and more enterprises are going to use javascript. Especially for mobile applications and response designs with html5 and websockets, it will lead to enormous code bases. Dynamic languages are great, but I do believe in typing models where it will benefit long run maintenance. Since TypeScript does exactly this (it is not a language but a tool for writing more robust javascript code) and for early adopters it will allow them to simple use the generated javascript files in case the tool is discontinued by Microsoft. I also think it makes more sense to use classes and interfaces and other structures like namespaces and modules, before compilation. This way the client browser is not bothered with handling those things (like would be the case when using for example backbone.js). There are other tools like Coffeescript, Dart, ... but I think TypeScript will allow plenty of people to transit from ASP.Net with c# development to more SPA development with structured javascript. Give it a try, at least until ECMAScript 6 will be supported by all major browsers :)
 
 
  • Javascript is missing Namespaces, Classes, Modules, Interfaces
  • TypeScript is a language for application scale JavaScript development.
  • Compiles to plain javascript.
  • Allows renaming/refactoring by type over your whole code base.
  • Intellisense and find reference.
  • Google closure is more like a type system in comments, while TypeScript incorporates anotations in the syntax.
  • TypeScript is open source written in TypeScript.
 
function process(x: string) {}
function process(x: number) {}
function process(x: bool) {}
function process(x: string[]) {}
function process(x: () => string) {} //x is a function that returns a string
function process(x: { a:number; b:string; }) {} 
 
interface IThing { 
a:number; 
b:string; 
c?:bool; //c is an optional property
 
foo(s: string):string;
foo(s: number):number; //overloading is possible, but you need to check in your one foo to return the correct model
//or so it has two overloads and a data property
foo {
(s: string):string;
(s: number):number;
data:any; 
}
 
new (s: string): Element; //constructor
 
[index: number]: Date;
function process(x: IThing) {} 
 
function Accumulator() : IAccumulator {}
  • The 'lib.d.ts' file contains the definitions for all classical javascript functions. (so you can use F12)
  • You can write or import these delaration files for other javascript frameworks like node.js, jquery, ...
class Point {
x: number;
y: number;
private color: string;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
//or shortcut, so you do not have to declare and assign the properties
constructor(public x: number = 0, public y: number) {} 
 
//Point.prototype.dist = function () {};
dist() { return Math.sqrt(this.x * this.x + this.y * this.y); }
//Object.defineProperty(Point.prototype, "dist", { get ... });
get dist() { return Math.sqrt(this.x * this.x + this.y * this.y); }
 
static origin = new Point(0,0);
}
var p = new Point(); p.x = 10; p.y = 20;
var p = new Point(10,20);
 
//inheritance
class Point3D extends Point {
constructor(x: number, y: number, z:number) {
super(x, y); //calls the base class
}
dist() {
var d = super.dist();
return Math.sqrt(d * d + this.z * this.z);
}
}
 
//auto self-this reference, by using arrow/lambda functions
class Tracker {
count = 0;
start() {
window.onmousemove = e => {
console.log(this.count);
}
}
}
 
//internal modules (open ended, can be used as namespaces}
module MyCore.Utils {
export class Tracker { ... }
}
var t = new MyCore.Utils.Tracker(); t.start();
 
import mu = MyCore.Utils;
var t = new mu.Tracker();
 
//external modules (commonjs and emd)
 
///<reference path="node.d.ts"/>
import http = module("http");
 
export function simpleServer(port: number, message: string) {
http.createServer((req,res) => {
res.writeHead(200, { "Content-Type": "text/html" });
res.write("<h1>" + message + "</h1>");
res.end();
}).listen(port);
}
 
import server = module("./server");
server.simpleServer(1337, "Greetings Channel 9");
console.log("Listening...");
Examples
  • ImageBoard using TypeScript, node.js, express and mongoDB.
  • Warship using TypeScript and jQuery, jQueryUI

Advanced HTML5 techniques - Notes 

Categories: HTML Notes

Advanced HTML5
Craig Shoemaker

1. Offline Applications
  • Browser Events + Application Cache
  • Manifest, Assets, Application Cache, Online Status Awereness 
<html manifest="journal-manifest.aspx">
 
CACHE MANIFEST
# version 1.1
 
CACHE:
journal.aspx
journal-css.aspx
scripts/jquery-1.5.1.min.js
offline.js
journal-bkg.jpg
 
NETWORK;
journal/list
 
FALLBACK:
/home /journal-fallback.aspx 
  • If one file gives a 404, none will work offline.
  • Network are pages you do not want to be cached.
  • Fallback if offline different from online.
  • The manifest must have mime type: text/cache-manifest with encoding utf-8.
 
Browser Caching (images, css, javascript)
Application Caching (manifest, html, images, css, scripts)
 
  • Do not mix browser with application caching!
 
Response Headers
Cache-Control: no-cache
Pragma: no-cache
Expires: -1 
  • window.applicationCache
  • checking - downloading - progress - cached (updated manifest)
  • checking - no update (if manifest not updated)
 
Cache States
0	UNCACHED	Cache not initialized
1 IDLE Cache not being updates
2 CHECKING Looking at manifest changes
3 DOWNLOADING Serving files in manifest to browser
4 UPDATEREADY All files in manifest are downloaded
5 OBSOLETE Contents of cache are stale and need to be downloaded again
 
this.Response.Cache.SetCacheability(HttpCacheability.NoCache);
<%@ Page ContentType="text/cache-manifest" ResponseEncoding="utf-8" ... >
 
offline.js
$(function() {
window.applicationCache.onupdateready = function(e) {
applicationCache.swapCache();
location.reload();
}
window.applicationCache.onchecking = function(e) {}
window.applicationCache.oncached = function(e) {}
window.applicationCache.onnoupdate = function(e) {}
window.applicationCache.onobsolete = function(e) {}
window.applicationCache.ondownloading = function(e) {}
window.applicationCache.onerror = function(e) {}
window.addEventListener("online", function(e) {}, true);
window.addEventListener("offline", function(e) {}, true);
}
 
function isOnline()
{
return navigator.onLine;
2. Geolocation 
  • One Time or Continual
 
IP Address: available everywhere, processed server side, low accuracy, high processing overhead
 
Coordinate Triangulation
GPS: high accuracy, long operation, not optimal for indoors, hardware required
WiFi: accurate, works indoors, quick & cheap response, ineffective in areas with limited access points
Cell Phone: fairly accurate, works indoors, quick & cheap response, Request access to cell phone or modem, ineffective in areas with few cell towers
 
User-Defined: high accuracy, flexibility to designate alternative locations, maybe fastest option, can be very inaccurate (esp. if locations change)
 
  • All major browsers from ie8.
 
Reset location permissions
IE - Options - Privacy - Location - Clear Sites
Chrome - Options - Under the hood - Privacy - Content Settings - Location - Manage Exceptions
Safari/Firefox/Opera - Processes each request individually
var options = {
enableHighAccuracy:true; //default is false
timeout:10000, //in milliseconds, default is no limit
maximumAge:1000 //in milliseconds, default is 0 which is recalculate immediately
};
navigator.geolocation.getCurrentPosition(showPosition, positionError, options);
 
watchId = navigator.geolocation.watchPosition(showPosition, positionError);
navigator.clearWatch(watchId);
3. Web Storage
  • Local + Session (per session, per domain)
  • Client-controlled between 2 and 10MB (mostly around 5MB)
  • Web storage has simple api with key/value pair (vs IndexedDB)
  • All browsers support (only IE supports storage event)
if (window.localStorage)
{
if( window.localStorage.myKey != null) {}
}
window.localStorage.removeItem("myKey");
var session = window.sessionStorage;
var dataString = JSON.stringify(data);
session.setItem("cart", dataString);
var data = JSON.parse(session.getItem("cart"));
 
window.addEventListener("storage", displayStorageEvent, false);
if (typeof(window.onstorage) == "undefinded") { alert('not for this browser'); }
function displayStorageEvent(e) {
$("#key").html(e.key);
$("#newValue").html(e.newValue);
$("#oldValue").html(e.oldValue);
$("#url").html(e.url);
// e.storageArea <- reference to either Local or Session instance 
}
 
var storage = window.localStorage;
try {
...
storage.length
storage.remainingSpace //only IE
...
} catch (e) {
...
QUOTA_EXCEEDED_ERR
...
}
 
storage.clear
4. Web Workers
  • Background threads in the browser. 
  • Dedicated to the window.
  • Shared to the browser, however not yet implemented in most browsers.
  • No access to DOM, Window, Host page (lot of libraries might not work)
  • You have access to Navigator(appName, appVersion, platform, userAgent), Timers, XmlHttpRequest
  • IE doesn't support it yet. (http://bit.ly/r5BSTI or http://bit.ly/oiOiLT for alternative solutions)
  • Arguments between UI and worker are copies.
function getWorker() {
if (_worker == null) {
_worker = new Worker("fib-worker.js");
_worker.onmessage = messageHandler;
_worker.onerror = errorHandler;
}
return _worker;
}
getWorker().postMessage(seriesLength);
getWorker().terminate(); //will terminate immediately
this.close(); //from within the worker will terminate on completion
 
function messageHandler(e) {
var results = e.data;
}
 
function generate(n) {
...
postMessage(results);
}
 
//basic ajax call
var xmlhttp;
if (XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
postMessage(xmlhttp.responseText);
}
}
xmlhttp.open("GET", "ajax-content.htm", true);
xmlhttp.send();
5. Web Sockets
  • Bidirectional, full duplex client/server communication.
  • Real time data before web sockets: ajax + comet 
 
Polling, long polling & streaming.
Http Header: 100's of bytes vs Socket Header: 2 bytes
 
Some browsers turn it off because of security.
firefox - about:config - network.websocket
opera - config#UserPrefs|EnableWebSockets
 
http://nugget.codeplex.com - c# web socket server implementation
interface ISocketServer
{
void Initialize(string serverPath, string originServerAndPort);
void Start();
void Send();
string Input { set; }
}
 
var server = new WebSocket("ws://localhost:8181/server");
server.addEventListener("message", messageHandler, false);
server.addEventListener("open", openHandler, false);
server.addEventListener("close", closeHandler, false);
function messageHandler(e) { logMsg("Server says: " + e.data); }
Stock Ticker example
  • jStockTicker.js to display the scrollbar.
  • NBuilder to generate dummy data.  
6. Microdata
  • Standard HTML Markup + Vocabulary namespace
<div id="container" itemscope itemtype="http://data-vocabulary.org/Person">
<h2 itemprop="name">Ken Van Gilbergen</h2>
<span itemprop="address" itemscope itemtype="http://data-vocabulary.org/Address">
<span itemprop="region">CA</span>
</span>
</div>
 
Microdata Property Value Origins
<img src="src" itemprop="photo" /> //will take source
<a href="link" itemprop="affiliation">some text</a> //will take href
<time itemprop="startDate" datetime="somedate">Feb 29, 9:00PM</time> //will take datetime attribute
itemid: uniquely identifies at scope-level
itemref: pointer to microdata values not included in itemscope 
itemref will contain a list of ids of elements separated by spaces.
<a href="mylocation" itemprop="url"><span itemprop="affiliation">MyCompany</span></a>
<meta itemprop="currency" content="USD">
 
 

Backbone.js Fundamentals - Notes 

Categories: Javascript Notes

Backbone.js
Liam McLennan

I like the model inheritance and statics of backbone. It is also really nice that you can replace the server-side with a local storage implementation. I do prefer the model binding of knockout however. Just seems more clean then the makes.

1. Introduction
 
Backbone.js gives structure to web applications by providing models with key-value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing API over a REstful JSON interface.
 
It's not a framework and it is not MVC.
 
 
SPA 
Pros: Fast, Highly interactive, Scalable
Cons: Extra work for SEO, Difficult to test, Security issues
 
Server side pages -> Hybrid Ajax pages -> SPAs client side
 
Task board SPA - http://trello.com
 
Required Dependencies
  • Underscore.js
  • jQuery or zepto
  • Zepto lightweight jquery compatible api used for mobile devices. - http://zeptojs.com/  
var book = new Backbone.Model({title:'white tiger', author:'Aravid'});
book.get('title'); // "White tiger"
book.set('title', 'Funny tiger');
book.toJSON();
http://jsfiddle.net/ynkJE/ - preconfigured for backbone testing
(function() {
var Rectangle = Backbone.Model.extend({});
var RectangleView = Backbone.View.extend({
tagName: 'div',
className: 'rectangle',
events: {
'click': 'move'
}
render: function() {
this.setDimensions();
this.setPosition();
return this; //backbone convention
},
setDimensions: function() {
this.$el.css({
width: this.model.get('width') + 'px',
height: this.model.get('height') + 'px'
});
},
setPosition: function() {
var position = this.model.get('position');
this.$el.css({
left: position.x,
right: position.y
});
},
move: function() {
this.$el.css('left', this.$el.position().left + 10);
}
});
 
var myRectangle = new Rectangle({
width:100, height:60, position: { x:300, y:150 }
});
 
var myView = new RectangleView({ model: myRectangle });
$('div#canvas').append(myView.render().el);
 
//when creating an array
//_(models).each(function(model) {
//$('div#canvas').append(new RectangleView({model:model}).render().el);
//});
})(); 
2. Models
var Vehicle = Backbone.Model.extend(
{
defaults: {
'color': 'white',
'type': 'car'
}
initialize: function() {
console.log('this is a contructor');
}
},
{
summary: function() {return 'a static function';}
}
);
console.log(Vehicle.summary()):
var car = new Vehicle(); //will run constuctor
var SuperCar = Vehicle.extend({});
var superCar = new SuperCar();
console.log(superCar instanceof SuperCar); //true
console.log(superCar instanceof Vehicle); //true
console.log(superCar instanceof Backbone.Model); //true
 
ford.set({
'maximumSpeed': '99',
'color':'blue',
'description', '<script>injection</script>'
});
ford.escape('description');
ford.has('type'); //check if attribute defined 
Models raise events when their state changes, detect by listening to change event.
ford.on('change', function () {}); //listen to change of object
ford.on('change:color', function () {}); //listen to change of property
Custom model events are identified by string identifiers.
var volcano = _.extend({}, Backbone.Events);
volcano.on('disaster:eruption', function(options){
console.log('duck and cover - ' + options.plan);
}); //namespacing events
volcano.trigger('disaster:erruption', {plan:'run'});
volcano.off('disaster:erruption');
 
var ford = new Backbone.Model({});
console.log(ford.id) //undefined, because not saved to server yet
console.log(ford.cid) //c0, temp id
console.log(ford.isNew()); //true
Validation is called prior to set and save operations.
var Vehicle = Backbone.Model.extend(
{
validate: function (attrs) {
var validColors = ['white','red'];
var colorIsValid = function (attrs)
{
if (!attrs.color) return;
return _(validColors).include(attrs.color); 
}
if (!colorIsValid(attrs)) {
return "color must be one of: " + validColors.join(",");
}
}
});
var car = new Vehicle();
car.on('error', function (model,error){
console.log(error);
});
car.set({'color','green'}, {
error: function (error) {
alert(error);
}
});
var attrs = ford.toJSON(); //converts a model's attributes to a javascript object
console.log(JSON.stringify(attrs)); //string representation
3. Views
  • DOM - View - Model : glue between models and documents
var V = Backbone.View.extend({
tagName:'li',
id:'thing',
className:'active',
attributes: {
'data-value': 12345
}
});
var v = new V();
$('body').prepend(v.el);
var V = Backbone.View.extend({});
var v = new V({el: '#test'});
v.$el.css('background-color','Yellow');
 
var v = new Backbone.View({el:'body'});
v.el // <body></body> the dom element
v.$el // cached $(this.el) [<body></body>] the jquery wrapper of that element
this.$ // this.$('selector') = this.$el.find('selector') scoped to current view 
 
var RefreshingView = Backbone.View.extend({
initialize:function() {
this.model.on('change', function() { this.render(); }, this);
},
render: function() {
this.$el.html(this.model.get('text'));
}
});
var m = new Backbone.Model({text:new Date().toString()});
var v = new RefreshingView({model:m, el:'body'});
v.render();
setInterval(function() { m.set({text:new Date().toString());},1000);
 
//<h3 class="not-imortant">first version</h3>
var el = new Backbone.View().make('h3', { class: 'not-important' } , 'first version'); 
 
v.remove() //$el.remove();  to remove view from DOM
 
//this.$('.clickable').click(handleClick);
var FormView = Backbone.View.extend({
events: {
'click .clickable': 'handleClick'
},
handleClick: function() {}
});
Guidelines
  • Do not attach to existing elements
  • Do not access DOM elements the view does not own
  • Pass el to the constructor of self-updating view
 
4. Templating
 
Client-side Templating
 
Underscore.js
<% ... %> //exececute arbitrary code 
<%= ... %> //evaluate an expression and render the result inline
<%- ... %> //evaluate an expression and render the html escaped result inline
<script id="latlon-template" type="text/html">
<%=lat%> <%=lon%>
<% ([1,2,3]).each(function(number) {%>
<p><%=number%></p>
<% }); %>
</script>
var V = Backbone.View.Extend({
render: function() {
var data = { lat:-27, lon=123 };
var template = $('#latlon-template').html();
this.$el.html(_.template(template,data));
return this;
}
}):
var v = new V({el:'body'});
v.render();
 
var compiled = _.template(source);
 Handlebars is templating engine based on mustache. (no code philosophy)
{{lat}} {{lon}}
{{#each numbers}}
<p>{{this}}</p>
{{/each}}
var compiled = Handlebars.compile(source);
var rendered = compiled({lat:-27}); 
Server-side Templating
handlebars <input> -f <output> //pre-compile file based templates
var rendered = Handlebars.templates.list(data);
 
5. Routing 
  • Don't use routing like mvc controllers!
var DocumentRouter = Backbone.Router.extend({
routes: {
'contents' : 'contents'
'view/:title': 'viewDocument'
},
contents: function(){
$('body').html(new ContentsView({collection:documents}).render().el);
}
viewDocument: function (title) {
var selectedDocument = _(documents).find(function (document) {
return document.get('title') == title;
}
$('body').empty().append(new DocumentView({model: selectedDocument}).render().el);
}
});
var router = new DocumentRouter();
Backbone.history.start();
router.navigate('contents', {trigger:true});
eventAggregator.on('document:selected', function(document){
var urlPath = 'view/' + document.get('title');
router.navigate(urlPath, {trigger:true});
}
window.history.pushState(...); //html5 history api, else backbone will use hash fragments
http://localhost/search/cats vs http://localhost/#search/cats
 
SEO
  1. Render content on the server
  2. #! Urls 
 
Backbone.history.start({pushState:false});
router.navigate('!search/cats', {trigger:true});
// generated url -> /#!search/cats
// google converts to -> /_escaped_fragment_=search/cats which will need server rendered content 
https://developers.google.com/webmasters/ajax-crawling/docs/specification
 
6. Collections 
  • Container for multiple models of the same type
  • Retrieve models from the server
  • Create models and save them to the server
  • Group models by some attribute
  • Collection is an array-like object (can't use square brackets)
var c = new Backbone.Collection([
{name:'thing'},
{name:'other'}
]);
console.log(c.length); //2
console.log(c.at(0)); // thing
 
var Vehicles = Backbone.Collection.extend({
model:vehicle,
comparator: function(vehicle) {
return vehicle.get('sequence');
}
comparator: function(vehicle1, vehicle2) {
return vehicle1.get('sequence') < vehicle2.get('sequence') ? -1 : 1;
}
});
var vehicles = new Vehicles(...);
vehicles.add({name:'Fred', age:6}); //will convert to backbone model
vehicles.remove(vechicles.at(1));
vehicles.on('add', function (model, col, options) { ... options.index ... };
vehicles.add({name:'Fred2', age:6}, {at:2, silent:true}); 
var v1 = vehicles.get(1);
var v2 = vehicles.getByCid('c0');
 
//proxy from underscore.js
collection.forEach(function (item { print(item); });
collection.forEach(print);
collection.map(function(item) { return transform(item); });
collection.reduce(function(memo,item) { return memo + item.get('age'); }, 0 );
var dave = collection.find(function(model) { return model.get('name') == 'Dave'; });
collection.on('remove', function(model, collection) {});
collection.on('change:name', function(model, options) {});
7. Connecting to a Server
  • CORS - Cross-origin resource sharing 
  • Origin is application layer protocol + domain name + port number
  • Cors is an alternative to jsonp (jsonp only has GET verb)
  • Cors supports all verbs but needs modern browser (IE10)
var MyModel = Backbone.Model.extend({
url: 'http://tra.la/mymodel'
});
myModelInstance.save({}, {
success: function() {}, //response will give id
error: function() {}
});
https://github.com/liammclennan/backbone-server (with node.js)
people.create({name:"Tom", age:50}); //http post to insert a model
people.fetch() //get array of models that must have an id
var person = new Person({id:0});
people.add(person); //will get url from the collection
person.fetch({ success: function() {...} });
person.set('age',18);
person.save();
person.destroy();
Backbone.sync
  • A function that interfaces between backbone and the server
  • Implements crud behavior and can be overridden globally, per collection, or per model
 
Backbone.localStorage
  • Sets backbone.sync to local browser storage
 
8. Testing with Jasmine (instead of Mocha or qUnit)
  • Test model specifications
  • Test views (rendered elements, raised events)
  • Testing routes (difficult, so keep routing easy)
 
beforeEach(function(){
rectangle = new app.Rectangle();
});
 
describe('some context', function(){
it('should show some observable behavior', function() {
//assert expectations here
expect(rectangle.area()).toBe(28);
expect(mySetFunction).toThrow(); // will give error
expect(rectangleView.el.tagName).toBe('DIV');
expect(rectangleView.$el.hasClass('rectangle')).toBe(true);
});
});
Testing without a browser
 
  • For QUnit you can use http://phantomjs.org/ 
  • (you can also use this to take screenshots)
  • phantomjs.exe run-jasmine-fixed.js SpecRunner.html //0 success 1 failure

Javascript for C# developers - Notes 

Categories: Javascript Notes

Javascript for C# developers
Shawn Wildermuth

 
I am convinced that with the upcoming of all those hybrid application platforms, more and more developers will need to know more and more javascript and related framework. People want to have responsive designs with local storage and prefer to have one code base instead of one for each platform they deploy on. With the release of Node.js people even start to write javascript on server side. Not so sure if that is a good idea, but for sure over time people will prefer to be comfortable with one language instead of the slight speed difference. 
This course by Shawn is short and since you can speed up the video at least at 2x, it will take you less then an hour to watch. It will give you a quick look into the loose typed javascript. Something most of us back-end developers are not so comfy with. Feel free to start using typescript or coffeescript to ease the pain. 

1. Javascript basics

Engines (depends on brower)
  • V8 in Chrome
  • Chakra in IE
  • Monkey in Firefox
 
JIT'ing is based on what browser you're running in.
 
 
Types are typically defined by structure not by identity
var x = 0;
var isNumber = typeof x == "number";
x = new Object(); //no problem, redefines x with new type
http://www.jslint.com/ - can do some type checks for you
 
Classic duck typing
function Feed(ani) { ani.Feed(); } 
function Move(object) { object.Move(); }
Dynamic Typing
var x = {
name: "Shawn",
city: "Atlanta"
};
x.phone = "404-123-1234";
x.makeCall = function () {
callSomeone(this.phone);
};
Global Scope
  • Objects at root are 'global'
 
Closures
  • References outside of function are accessible in function, regardless of lifetime
 
Type Coalescing
"test " + "me" //test me
"test " + 1 //test 1
"test " + true //test true
"test " + (1==1) //test true
100 + "25" //10025
 
1 == "1"; //true
1 === "1"; //false - equality without coalescing
1 !== "1"; //true 
Value Types: boolean, string, number 
if ("hello") {} //true
if ("") {} //false
if (25) {} //true
if (0) {} //false
if (10/0) {} //false (NaN)
var a = null; if (a) {} //false
var u = "One" + "Two";
var single = u[4]; //'T'
log(u.length); //6
  • The number type holds IEEE-754 format which is prone to rounding errors.
var c = 080; //octal starting with zero
var d = 0xffff; //hex
var e = 1.34e6;
 
Number.MIN_VALUE;
Number.MAX_VALUE;
Number.POSITIVE_INFINITY;
Number.NEGATIVE_INFINITY;
 
var fail = 10/0; // NaN
var test1 = NaN == NaN; //false
var test2 = isNaN(NaN); //true
Reference Type: object 
var more = {
"moniker": 1,
height: 4.3,
subData {
option: true,
flavor: "vanilla"
}
}
var a = [ "hello", "goodbye" ];
a.length;
a.push({}); //add to end
var obj = a.pop(); //remove from end
a.shift(); //remove from beginning
a.unshift({}); //add to beginning
var where = c.indexOf(obj);
where = c.lastIndexOf(obj);
//etc. slice, splice, concat
Delegate Type: function
  • Data type much like Func<>
 
Special Type: undefined, null, NaN
var a = null; // "null"
var b = c; // "undefined" 
2. Functions
function foo(one, two, three) {
alert(one);
if (two) alert(two);
if (three) alert(three);
}
  • However there is no overloading, the last definition will override the previous.
  • The arguments.length is available inside function body.
  • Declared parameters do not matter. (arguments[x])
  • All functions return a value, it will return undefined if non existing.
var log = function(s) { alert("yes"); }
function log(s) { alert("yes"); }
var x = log.length; //1 paramter
var y = log.name; //"log"
var z = log.toString(); //"function log(s) { alert("yes"); }"
  • "this" applies to the owner of the function
var f = function() { alert(this); };
f(); // [Object Window]
  • bind() lets you change the owner (context)
var f = obj.myFunc.bind(this); 
f(); //this == global object
Functions define scope
var a = "Hello";
if (true) { var b = a; }
var c = b; //this works
var a = "Hello";
function () { var b = a; }
var c = b; //this doesn't work
  • Anonymous self-executing function protects the global namespace by function scope
  • Javascript lacks real namespaces!
(function(ns) {
var currentDate = new Date();
ns.currentTime = function (){
return currentDate;
};
})(window.MyNamespace = window.MyNamespace || {});
3. Object Oriented Javascript
var name = cust.name;
var nameAlso = cust["name"];
var company = cust."company name"; //does not work
var company = cust["company name"];
  • Dynamic objects work the same as c# dynamic foo = new ExpandoObject();
  • We can mimic c# class unit of work in javascript.
  • Use capital case for functions that are used as classes.
function Customer(name, company) {
//public
this.company = company;
//private
var mailServer = "mail.google.com";
var _name = name;
this.sendEmail = function (email) { sendMailViaServer(mailServer); };
//only use if really needed
Object.defineProperty(this, "name",{
get: function() { return _name; },
set: function(value) { _name = value; }
});
}
var cust = new Customer("Shawn", "Wilder Minds");
var name = cust.name;
cust.sendEmail("foo@test.foo");
 
//Static members
Customer.mailServerToo = "mail.google.com";
var svr = cust.mailServerToo; //doesn't work
var svr = Customer.mailServerToo;
 
//The prototype object
Customer.prototype.mailServer = "Tralala";
Customer.prototype.send = function (email) { 
var svr = this.maiLServer;
};
 
//Inheritance
var test = a instanceof Animal; //true
Cow.prototype = new Animal("Hay");
var c = new Cow("White");
c.feed(); //defined on a
var test2 = c instanceof Animal; //true
var test3 = c instanceof Cow; //true
  • Abstract class is possible, but better to avoid.
  • Protected is not possible.
  • Interfaces aren't necessary, use duck typing.
 
Enumerating Members (reflection)
for (var prop in cust) {
alert(prop); //name
alert(cust[prop]); //value
}
var has = cust.hasOwnProperty("name");
var isEnum = cust.propertyIsEnumerable("name");
  • Extension Methods: add to existing type's prototype.
4. Practical lessons
  • ECMAScript v5 allows more strictness. 
  • "use strict";
  • for..in returns the indexer not the object like in a c# foreach
svr.send({
to: "someone@somewhere.com",
from: "someone@somewhereelse.com",
body: "hello",
subject: "test",
complete: function(r) { alert("Success: " + r); },
error: function(e) { alert("Failed: " + e); }
});
 
SmtpClient.prototype.send = function(msg) {
var defaults = {
to: "bla@blo.bli"
};
$.extend(defaults, msg); //jQuery
var to = default.to;
};
Architecting large javascript codebases
Page 29 of 43 << < 20 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 40 > >>