1. Very Freaking Advanced JavaScript

    Marko Mrdjenovič / friedcell.net

    Disclaimer: All code made for this presentation. Use: [PgUp]/[PgDn] to change slides, +/- to change code font, double click code samples to edit. Resize thw fonts in your browser to fit the screen, if you're lost find me - @friedcell.

  2. Not really

    1. Just Scope
    2. and Closures
  3. Scope

  4. Global scope

    a = "ping";
    function test() {
    	alert(a);
    }
    test();
  5. Global scope

    a = "ping";
    function test() {
    	a = "pong";
    	alert(a);
    }
    test();
    alert(a);
  6. Local scope

    a = "ping";
    function test() {
    	var a = "pong";
    	alert(a);
    }
    test();
    alert(a);
  7. Scope handling code

    // scope = [{}];
    /*
    function findInScope(prop) {
    	var i = 0, j = scope.length, layer = null;
    	for (; i < j; i += 1) {
    		layer = scope[i];
    		if (layer[prop]) {
    			return layer[prop];
    		}
    	}
    	return undefined;
    }
    */
  8. A few code examples

    var a = "ping";
    // scope = [{a:"ping"}]
    function test() {
    	// scope = [{}].concat(executionScope) => [{},{a:"ping"}]
    	var a = "pong";
    	// scope = [{a:"pong"},{a:"ping"}]
    	alert(a);
    }
    test();
    alert(a);
  9. A few code examples

    // scope = [{}];
    var a = "ping";
    // scope = [{a:"ping"}]
    function test() {
    	// scope = [{}].concat(executionScope) => [{},{a:"ping"}]
    	var a = "pong";
    	// scope = [{a:"pong"},{a:"ping"}]
    	function msg() {
    		// scope = [{}].concat(executionScope) => [{},{a:"pong"},{a:"ping"}]
    		alert(a);
    	}
    	msg();
    	// execute msg with executionScope = [{a:"pong"},{a:"ping"}]
    	alert(a);
    }
    test();
    alert(a);
  10. A few code examples

    // scope = [{}];
    var a = "ping";
    // scope = [{a:"ping"}]
    function test() {
    	// scope = [{}].concat(executionScope) => [{},{a:"ping"}]
    	var a = "pong";
    	// scope = [{a:"pong"},{a:"ping"}]
    	function msg() {
    		// scope = [{}].concat(executionScope) => [{},{a:"pong"},{a:"ping"}]
    		a = "dong";
    		// scope = [{}, {a:"dong"},{a:"ping"}]
    		alert(a);
    	}
    	// execute msg with executionScope = [{a:"pong"},{a:"ping"}]
    	msg();
    	alert(a);
    }
    test();
    alert(a);
  11. A few code examples

    // scope = [{}];
    var a = "ping";
    // scope = [{a:"ping"}]
    function test() {
    	// scope = [{}].concat(executionScope) => [{},{a:"ping"}]
    	var a = "pong";
    	// scope = [{a:"pong"},{a:"ping"}]
    	function msg() {
    		// scope = [{}].concat(executionScope) => [{},{a:"pong"},{a:"ping"}]
    		var a = "dong";
    		// scope = [{a:"dong"}, {a:"pong"},{a:"ping"}]
    		alert(a);
    	}
    	// execute msg with executionScope = [{a:"pong"},{a:"ping"}]
    	msg();
    	alert(a);
    }
    test();
    alert(a);
  12. This / object scope

    a = "ping";
    function test() {
    	alert(this.a);
    }
    test();
  13. This / object scope

    a = "ping";
    function test() {
    	alert(this.a);
    }
    test();
    test.call({a:"pong"});
  14. This / object scope

    a = "ping";
    function test() {
    	alert(this.a);
    }
    test();
    test.call({});
  15. This / object scope

    a = "ping";
    function test() {
    	// executionScope = [{a:"ping"}]
    	function msg() {
    		// executionScope = [{},{a:"ping"}]
    		alert(this.a);
    	}
    	msg();
    	alert(this.a);
    }
    test();
    test.call({a:"dong"});
  16. Object methods

    a = "ping";
    // create a new object with a property and a method
    o = {
    	a: "pong",
    	// create an anonymous function
    	// and set it as a value to an object member
    	test: function () {
    		alert(this.a);
    	}
    };
    o.test();
  17. Object methods

    a = "ping";
    // create a named function "msg"
    function msg() {
    	alert(this.a);
    }
    o = {
    	a: "pong",
    	// create a reference to the named function 
    	// as an object member
    	test: msg
    };
    o.test();
  18. Object methods

    a = "ping";
    // create a new object with a property and a method
    o = {
    	a: "pong",
    	test: function () {alert(this.a);}
    };
    // create another object with a reference to o.test as a method
    n = {
    	a: "dong",
    	test: o.test
    };
    // create a reference to the function object
    fn = o.test;
    o.test();
    o.test.call({a:"king"});
    n.test();
    fn();
    fn.call({a:"kong"});
  19. Closures

  20. Definition?

    1. Function returning a function that remembers everything.
  21. You probably know

    var a = [];
    for (var i = 0; i < 5; i++) {
    	a[i] = function () {
    		alert(i);
    	}
    }
    a[2]();
  22. The right way

    var a = [];
    for (var i = 0; i < 5; i++) {
    	a[i] = (function (j) {
    		return function () {
    			alert(j);
    		};
    	}(i));
    }
    a[2]();
  23. Useful for

    1. Caching
    2. Hiding / namespacing
    3. Scoring
    4. Remembering
  24. Caching

    nospace = (function () {
    	var rgx = / /g;
    	return function (s) {
    		return s.replace(rgx, '');
    	};
    }());
    alert(nospace('some text here'));
  25. Hiding / namespacing

    NS = (function () {
    	var secret = 3;
    	function a() {
    		return secret;
    	}
    	return {test: a};
    }());
    alert(NS.secret);
    alert(NS.test());
  26. Scoring

    var options = [[1,2], [7,4], [2,4]],
    	scores = [];
    for (var i = 0; i < options.length; i++) {
    	scores[i] = {
    		score: options[i][0] * options[i][1], 
    		exec: (function (d) {
    			return function () {
    				return d;
    			};
    		}(options[i]))
    	};
    }
    scores.sort(function (a, b) {return a.score < b.score ? 1 : -1;});
    alert(scores[0].exec());
  27. Remembering

    H = (function () {
    	var s = 0, b = function () {};
    	function f() {
    		var os = s, ob = b;
    		b = function () {
    			s = os;
    			b = ob;
    		};
    		s += 1;
    	}
    	return {
    		f: function () {f();alert(s);},
    		b: function () {b();alert(s);}
    	};
    }());
    H.f();
    H.f();
    H.b();
    H.b();
  28. Memory leaks

    H = (function () {
    	var elm = $('#keeper');
    	return function () {
    		alert(elm.text());
    	};
    }());
    $('#keeper').remove();
    H();
  29. The end.

    1. Questions?
    2. @friedcell