# Prinzipien
Wissen
Werkzeuge
Wiederholung
# Wissen
Know the pitfalls
![pitfalls](images/banana_peel.png)
## Implied globals
Forgetting var
```javascript contenteditable
var foo = function() {
bar = 1;
};
```
## Boolean type conversion
To Truthy or to Falsy. That is the *only* question!
```javascript contenteditable
var el = document.getElementById('does_not_exist');
if(el == false) {
alert("shouldn't we see this message?!");
}
```
## Trailing comma
works on my machine!
```javascript contenteditable
var foo = {
bar: "bar",
baz: "baz",
};
```
## Return undefined
señor developers wear mustaches
{
```javascript contenteditable
var foo = function() {
return
{
x : "looks like C# now!"
};
}
```
## Associative arrays
they don't exist
```javascript contenteditable
var x = [];
x['foo'] = "bar";
```
## try .. catch .. finally
who cares about the reason?
```javascript contenteditable
var foo = function() {
try {
doCrazyStuff;
} catch (e) {
return false;
}
return true;
};
```
## Hoisting
declare upfront all variables
```javascript contenteditable
var foo = "global";
var bar = function() {
alert(foo);
var foo = "local";
alert(foo);
};
```
## Eval
... and the job is done
```javascript contenteditable
function poorMansJsonParser(text) {
return eval("(" + text + ")");
}
var text = ' { "hello" : "world" } ';
var json = poorMansJsonParser(text);
```
## Eval is evil!
Never ever!
```javascript contenteditable
var text = ' function() { alert("hacked!"); })( ';
```
## Globals
the mother of all antipatterns
```javascript contenteditable
function foo() {
return "bar";
}
console.log(this['foo']());
```
![kitteh](images/kitteh.jpg)
Every time you clutter the global namespace,
somewhere in the world a helpless kitten dies!
# Wissen
Pretty Code
![tools](images/mustache.png)
## Globals
reduce, minimize, delete or kill them
```javascript contenteditable
(function() { "wtf?" })();
```
## The switch-case syndrome
a functional language wants functions!
```javascript contenteditable
switch (something) {
case 1:
doFirst();
break;
case 2:
doSecond();
break;
case 3:
doThird();
break;
}
```
## Lookup tables
avoid the switch-case syndrome
```javascript contenteditable
var methods = {
1: doFirst,
2: doSecond,
3: doThird
};
if (methods[something]) {
methods[something]();
}
```
## Revealing Module Pattern
```javascript contenteditable fragment
var myRevealingModule = function () {
var _name = "Johannes";
function greetings() {
console.log("Hello " + _name);
}
function setName(name) {
_name = name;
}
return {
setName: setName,
greetings: greetings
};
}();
```
[» Documentation](http://addyosmani.com/resources/essentialjsdesignpatterns/book/#revealingmodulepatternjavascript)
## Modul loaders
use AMD (require.js)
```javascript contenteditable fragment
define('test', ['jquery'], function() {
return {
saySomething : function() { alert("hello!"); }
}
});
require(['test'], function(t) {
t.saySomething();
});
```
## Events
Publish/Subscribe Pattern
```javascript contenteditable
var $events = $({});
$events.bind('somethingHappens', function() {
alert("Something happened!");
});
$events.trigger('somethingHappens');
```
# Werkzeuge
![tools](images/tool.png)
* Visual Studio 2010/2012
* [JScript Editor Extensions](http://visualstudiogallery.msdn.microsoft.com/872d27ee-38c7-4a97-98dc-0d8a431cc2ed)
* [Resharper 7.1](http://www.jetbrains.com/resharper/whatsnew/#javascript)
* [JSHint](http://www.jshint.com/platforms/)
* [Chutzpah](http://chutzpah.codeplex.com/)
* [Firebug](https://getfirebug.com/) / F12
![Jasmine](images/jasmine_logo.png")
_TDD with [Jasmine](http://pivotal.github.com/jasmine/)_
## Why Jasmine?
BDD-style
similar to JSpec or RSpec, created by authors of jsUnit and Screw.Unit
independent
from any browser, DOM, framework or host language
integrates
into continuous build systems
## Jasmine Bootstrap
```html contenteditable small
_LT_!DOCTYPE html_GT_
_LT_html_GT_
_LT_head_GT_
_LT_title_GT_Jasmine Spec Runner_LT_/title_GT_
_LT_link rel=_QUOT_stylesheet_QUOT_ href=_QUOT_lib/jasmine-1.3.1/jasmine.css_QUOT_ /_GT_
_LT_script src=_QUOT_lib/jasmine-1.3.1/jasmine.js_QUOT__GT__LT_/script_GT_
_LT_script src=_QUOT_lib/jasmine-1.3.1/jasmine-html.js_QUOT__GT__LT_/script_GT_
_LT_!-- include source files here... --_GT_
_LT_script src=_QUOT_src/Player.js_QUOT__GT__LT_/script_GT_
_LT_script src=_QUOT_src/Song.js_QUOT__GT__LT_/script_GT_
_LT_!-- include spec files here... --_GT_
_LT_script src=_QUOT_spec/SpecHelper.js_QUOT__GT__LT_/script_GT_
_LT_script src=_QUOT_spec/PlayerSpec.js_QUOT__GT__LT_/script_GT_
_LT_script_GT_
(function () {
var htmlReporter = new jasmine.HtmlReporter();
var jasmineEnv = jasmine.getEnv();
jasmineEnv.addReporter(htmlReporter);
jasmineEnv.specFilter = function (spec) {
return htmlReporter.specFilter(spec);
};
var currentWindowOnload = window.onload;
window.onload = function () {
if (currentWindowOnload) { currentWindowOnload(); }
jasmineEnv.execute();
};
})();
_LT_/script_GT_
_LT_/head_GT_
_LT_body_GT_
_LT_/body_GT_
_LT_/html_GT_
```
## Output
## Hello World
```javascript contenteditable
var helloWorld = function() {
return "Hello World!";
};
describe('helloWorld', function() {
it('says hello', function() {
expect(helloWorld()).toEqual("Hello World!");
});
});
jasmine.getEnv().execute();
```
hint: press F12 and paste this code!
# Wiederholung
# 形
If I would have had time...
## You will never have time!
* __Learn__ TDD
* __Improve__ by self reflection
* __Improve__ by feedback of others
* __Help__ others to improve
* __Teach__ TDD
* __Learn__ a new language
## Test-Driven Development
1. Write your tests
1. Watch them fail
1. Make them pass
1. Refactor
1. Repeat
see [Growing Object-Oriented Software, Guided by Tests](http://www.amazon.de/dp/0321503627), page 6
see [Working Effectively with Legacy Code](http://www.amazon.de/dp/0131177052), page 62 or many other
## 1. Write your test
```javascript contenteditable
describe("saveFormat", function () {
var original = '{0} - {1} - {2}';
it("should replace placeholders", function () {
var expected = 'A - B - C';
var formated = saveFormat(original, 'A', 'B', 'C');
expect(formated).toEqual(expected);
});
it("should encode injected content", function () {
var expected = 'A - _AMP_lt;b_AMP_gt;TEST_AMP_lt;/b_AMP_gt; - C';
var formated = saveFormat(original, 'A', '_LT_b_GT_TEST_LT_/b_GT_', 'C');
expect(formated).toEqual(expected);
});
});
```
## 2. Watch them fail
```javascript contenteditable
var saveFormat = function() {
return "boo!";
};
jasmine.getEnv().execute();
```
Demo
## 3. Make them pass
```javascript contenteditable
var saveFormat = function(txt) {
$(arguments).each(function (i, item) {
if (i _GT_ 0) {
item = ($('_LT_div/_GT_').text(item).html());
txt = txt.replace("{" + (i - 1) + "}", item);
}
});
return txt;
};
jasmine.getEnv().execute();
```
Demo
## 4. Refactor
```javascript contenteditable
function htmlEncode(input) {
return ($('_LT_div/_GT_').text(input).html());
}
var saveFormat = function(txt) {
$.each(arguments, function (i, item) {
if (i _GT_ 0) {
item = htmlEncode(item);
txt = txt.replace("{" + (i - 1) + "}", item);
}
});
return txt;
};
jasmine.getEnv().execute();
```
Demo
## 5. Repeat
```javascript contenteditable
function htmlEncode(input) {
return ($('_LT_div/_GT_').text(input).html());
}
var saveFormat = function() {
var args = Array.prototype.slice.call(arguments);
var txt = args.shift();
$.each(args, function (i, item) {
item = htmlEncode(item);
txt = txt.replace("{" + i + "}", item);
});
return txt;
};
jasmine.getEnv().execute();
```
Demo
## Deep practice
[codekata.pragprog.com](http://codekata.pragprog.com)
[katas.softwarecraftsmanship.org](http://katas.softwarecraftsmanship.org/)
# Danke!
![QR-Code http://bit.ly/slides_dwx](images/bit.ly__slides_dwx.png)
[blog.johanneshoppe.de](http://blog.johanneshoppe.de/2013/06/dwx-developer-week/)