Skip to content

Instantly share code, notes, and snippets.

@roachhd
Created November 26, 2014 05:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save roachhd/12cd60e8f96958d11435 to your computer and use it in GitHub Desktop.
Save roachhd/12cd60e8f96958d11435 to your computer and use it in GitHub Desktop.
JAVASCRIPT - The Good Bits. slideshow with markdown
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>JavaScript: The Good Parts</title>
<script src="//gnab.github.io/remark/downloads/remark-0.5.9.min.js" type="text/javascript"> </script>
<style type="text/css" media="screen">
@import url(//fonts.googleapis.com/css?family=Droid+Serif);
@import url(//fonts.googleapis.com/css?family=Yanone+Kaffeesatz);
body { font-family: 'Droid Serif'; }
h1, h2, h3 {
font-family: 'Yanone Kaffeesatz';
font-weight: 400;
margin-bottom: 0;
margin-top: 10px;
}
h1 { font-size: 3.5em; }
h2 { font-size: 3em; }
h3 { font-size: 1.6em; }
.inverse {
background: #272822;
color: #777872;
text-shadow: 0 0 20px #333;
}
.inverse h1, .inverse h2 {
color: #f3f3f3;
line-height: 0.8em;
}
pre {
border-left: 0.4em solid #d7d7d7;
padding: 1em !important;
}
code {
background: transparent !important;
}
a {
color: #F92672;
text-decoration: none;
}
.task {
float: right;
font-size: 0.9em;
padding-top: 0.6em;
}
.task a {
color: #080;
text-decoration: none;
}
.right {
float: right;
margin-left: 1em;
}
.pushdown {
margin-top: 12em;
}
</style>
</head>
<body>
<textarea id="source">
class: center, middle, inverse
# JavaScript: The Good Parts
### by [@gnab](http://twitter.com/gnab) &amp; [@torgeir](http://twitter.com/torgeir)
---
# The Book
.right[![JavaScript: The Good Parts](thebook.png)]
Short, exclusively about JavaScript.
- "_Intended for programmers venturing into JavaScript for the first time_"
- "_... also indented for programmers who have been working with JavaScript at a novice level, and are now ready for a more sophisticated relationship with the language_"
- "_This is not a book for beginners_"
- "_This is not a book for dummies_"
???
- Crockford som har skrevet både bok og JSLint (luke ut ulumskheter)
- editorjs - online editor m/ oppgaver, kjøring og linting
- Fokus kun på språk, ikke rammeverk / arkitektur
---
class: center, middle
## Editor
### [http://js-workshop.herokuapp.com](http://js-workshop.herokuapp.com)
## Slides
### [http://gnab.github.com/js-workshop](http://gnab.github.com/js-workshop)
## Code
### [http://github.com/gnab/js-workshop](http://github.com/gnab/js-workshop)
---
name: default
layout: true
task: &nbsp;
.task[{{task}}]
---
class: center, middle, inverse
# Object Literals
???
Objekter, arrays og typer
---
template: default
layout: true
### Object Literals
---
task: [#01 Object properties](http://js-workshop.herokuapp.com/#1/1)
# Objects
A collection of key-value properties.
var obj = {
key1: 'value1',
key2: 13
};
obj.key1; // 'value1'
obj['key2']; // 13
obj.key3; // undefined
delete obj.key1;
obj.key1; // undefined
???
- Aksess av felter både ved . og []
- Manglende felt gir undefined, ikke feil
---
task: [#02 Populating arrays](http://js-workshop.herokuapp.com/#1/2)
# Arrays
A collection of indexed properties.
var arr = [1, "two", 3];
arr.push(4);
arr[1]; // "two"
arr[3] = 4;
arr.length; // 4
???
- Dynamisk størrelse
- Vilkårlige typer objekter
- .length
---
# Objects vs. Arrays (1/2)
Arrays are not "real":
- Objects in disguise
- Operations are slow when number of elements are large
var obj = [1, 2, 3];
obj.speed = 5;
obj[1]; // 2
obj.speed // 5
obj['speed']; // 5
obj.length; // 3
???
.length baserer seg på "array" innhold, ikke andre felter
---
task: [#03 What have you got?](http://js-workshop.herokuapp.com/#1/3)
# Objects vs. Arrays (2/2)
The `for (... in ...)` loops all properties of an object.
var obj = [1, 2, 3];
obj.speed = 5;
var i;
for (i = 0; i < obj.length; ++i) {
obj[i]; // 1, 2, 3
}
var key;
for (key in obj) {
obj[key]; // 1, 2, 3, 5
}
---
task: [#04 Who are you?](http://js-workshop.herokuapp.com/#1/4)
# Types
Go figure.
new Object(); // {}
new Array(); // []
new Number(1); // 1
new Boolean(true); // true
typeof {}; // 'object'
typeof []; // 'object' WTF?
typeof 1; // 'number'
typeof ''; // 'string'
typeof true; // 'boolean'
typeof null; // 'object' WTF?
???
- Foretrukket å ikke bruke new (kan utelates og gi feil resultat)
- typeof [] gir mening, men kan ikke skille typene
- typeof gir alltid streng
- typeof må brukes for å sjekke eksistens (men ikke for objektfelter)
---
layout: false
class: center, middle, inverse
# Functions
---
template: default
layout: true
### Functions
---
# You name it
function () {}
function add (a, b) {
return a + b;
}
var multiply = function (a, b) {
return a * b;
};
var recur = function rec (num) {
if (num === 0) { return num; }
return rec(num - 1);
};
???
- Function expressions vs statements
- Hoisting - add tilgjengelig overalt
- Kan lagre (anonyme) funksjoner i variabler
- Navngitt funksjon privat ved tilordning (recur / rec)
---
task: [#01 How many arguments do you have?](http://js-workshop.herokuapp.com/#2/1)
# arguments
All functions can access their:
- `arguments`
- `length`
- `callee`
function countArgs () {
return arguments.length;
}
countArgs(); // 0
countArgs('one'); // 1
countArgs('one', 'two'); // 2
???
- arguments ikke array, men objekt med length-felt
- callee - funksjonen selv, den som blir kalt
- Oppgave løses med for, ikke for in
- Siste definisjon av funksjon med samme navn gjelder
- Funksjon kan kalles med vilkårlig antall argumenter uavh. av definisjon
---
task: [#02 Higher order functions](http://js-workshop.herokuapp.com/#2/2)
# First order variables
- Functions can return functions
- Functions can take functions as an argument
function createFunction () {
return function () {
};
}
var anonymous = createFunction();
anonymous(); // undefined
---
# Scope (1/2)
JavaScript has __function scope__, not block scope.
function () {
i; // undefined WTF?
for (var i = 0; i < 10; i++) {
}
i; // 10
}
???
Uten var i hadde man fått ReferenceError
---
# Scope (2/2)
Variable declarations towards the top, please!
function () {
var i;
for (i = 0; i < 10; i++) {
}
i; // 10
}
???
Hoisting - skjer implisitt, så greit å gjøre synlig
---
# More on scope (1/3)
Functions can access everything from their outer scope.
var a = 1;
function doSomething () {
a; // 1
function doMore () {
a; // 1
}
}
---
# More on scope (2/3)
Not the other way around.
function doSomething () {
var b = 1;
function doMore () {
b; // 1
}
}
doSomething();
b; // ReferenceError
???
Funksjon kan kjøres når expression - vanlig med () rundt for å gjøre til expr.
---
task: [#03 JavaScript pwns your scope](http://js-workshop.herokuapp.com/#2/3)
# More on scope (3/3)
Forgot the __`var`__? You've got yourself a global!
function doSomething () {
c = 1;
function doMore () {
c; // 1
}
}
doSomething();
c; // 1
---
task: [#04 Variables by reference](http://js-workshop.herokuapp.com/#2/4)<br /> [#05 Binding scope](http://js-workshop.herokuapp.com/#2/5)
# Closures (1/3)
Functions can bind scope, even after their outer function has returned!
var counter = function () {
var i = 0;
return function () {
return i++;
};
};
var inc = counter();
inc(); // 0
inc(); // 1
---
task: [#06 Globally ugly, privately slow, closingly sweet](http://js-workshop.herokuapp.com/#2/6)<br />[#07 Variables by reference](http://js-workshop.herokuapp.com/#2/7)
# Closures (2/3)
Functions can run immediatly!
var inc = function () {
var i = 0;
return function () {
return i++;
};
}(); // Note the trailing ()!
inc(); // 0
inc(); // 1
---
# Closures (3/3)
Create modules with private state!
var lib = {};
lib.module = (function () {
var privateVariable;
var privateFunction = function () {};
return {
publicProperty: 1,
privilegedMethod: function (arg) {
// privateVariable = arg;
}
};
})();
---
# Context
- Functions run in different contexts
- Depending on how they are invoked
- May be invoked in 4 primary ways
- Function invocation
- Constructor invocation
- Method invocation
- `apply`/`call` invocation
---
task: [#08 What is this?](http://js-workshop.herokuapp.com/#2/8)
# Function invocation
Functions called directly.
var countArgs = function () {
// this === window
return arguments.length;
};
countArgs(); // 0
???
I nodejs ville this ikke være window, men exports.
---
task: [#09 Constructing objects](http://js-workshop.herokuapp.com/#2/9)
# Constructor invocation (1/2)
Functions called with the __`new`__ keyword.
function Person (name) {
// this === instance of Person
this.name = name;
}
var bob = new Person('bob');
var ed = new Person('ed');
ed.name = 'fred';
---
# Constructor invocation (2/2)
But there's a gotcha!
function Person (name) {
this.name = name;
}
var bob = Person('bob');
var ed = new Person('ed');
window.name === 'bob' // true WTF?
---
task: [#10 Context confusion](http://js-workshop.herokuapp.com/#2/10)
# Method invocation
Functions called on objects.
var obj = {
value: 1,
getValue: function () {
// this === obj
return this.value;
}
};
obj.getValue() // 1
---
task: [#11 Is this yours?](http://js-workshop.herokuapp.com/#2/11)
# apply/call invocation
Applying functions to objects.
function doStuff () {
return this.speed;
}
var obj = { speed: 2 };
doStuff.apply(obj, [ arg1, arg2 ]); // 2
doStuff.call(obj, arg1, arg2); // 2
---
layout: false
class: center, middle, inverse
# Inheritance
---
layout: true
template: default
### Inheritance
---
# Multiple paradigms
- Pseudoclassical inheritance
- Prototypal/differential inheritance
- Functional inheritance
???
- Ullent område
- Mange gjør forskjellig
- Prøver å etterligne andre språk
- JavaScript kan tilpasses flere paradigmer
---
# Prototype (1/3)
- Inherit directly from other objects
- Properties
- Methods
- All objects inherit from a `prototype` property
- Bound upon object creation
var obj = {};
obj.toString(); // '[object Object]'
---
# Prototype (2/3)
The `prototype` property.
function Object () {}
Object.prototype = {
toString: function () {
return '[object Object]';
}
};
var obj = new Object();
obj.toString(); // '[object Object]'
---
# Prototype (3/3)
var first = new Object();
// first.__proto__ = Object.prototype;
first.x = 1; // on first
first.toString(); // on first's prototype (Object)
![Prototypal Inheritance 1](prototype1.png)
---
task: [#01 Pseudoclassical 1](http://js-workshop.herokuapp.com/#3/1)
# Pseudoclassical inheritance (1/2)
.right.pushdown[![Prototypal Inheritance 2](prototype2.png)]
function CoolObject (x) {
this.x = x;
}
CoolObject.prototype = {
getX : function () {
return this.x;
}
};
var coolObj = new CoolObject(1);
???
- Prototype-objektet deles av alle instanser, hvert objekt arver ikke alt
- Minner om statiske klassevariabler/metoder
- Kan endre ting på prototypen i etterkant - vil påvirke alle instanser
- Kan endre prototype for objekt etter opprettelse
- Husk at = { .. tilsvarere new Object()
---
task: [#02 Pseudoclassical 2](http://js-workshop.herokuapp.com/#3/2)
# Pseudoclassical inheritance (2/2)
- Intented to look object oriented - looks quite alien?
- Remember to use __`new`__!
- Clobbering global variables
- No compile warning, no runtime warning
- Convention - all constructor functions start with an capital letter
"_Comfort to unexperienced JavaScript programmers_"
"_Induce unnecessary complex hierarcies_"
"_... motivated by constraints of static type checking_"
__JavaScript has more and better options__
???
- Bedre å pakke inn new for å unngå å etterligne andre språk
- Veldig likt obj := Object clone i Io
---
task: [#03 Prototypal](http://js-workshop.herokuapp.com/#3/3)
# Prototypal/differential inheritance
- Dispence with classes, make useful objects
- Specify differences
function create (proto) {
function F () {};
F.prototype = proto;
return new F();
}
var eventBase = {
emit: function () {},
on: function () {}
};
var obj = create(eventBase);
obj.emit('some event');
---
task: [#04 Functional](http://js-workshop.herokuapp.com/#3/4)
# Functional inheritance (1/2)
var person = function (options) {
var that = {};
that.getName = function () {
return options.name;
};
return that;
};
var bob = person({ name: 'bob' });
var ed = person({ name: 'ed' });
???
Ulempe at alle instanser får egne kopier av funksjoner
---
# Functional inheritance (2/2)
function Car (options) {
this.getColor = function () {
return options.color;
};
}
Car.proto...
var car = new Car({ color: 'red' });
car.getColor(); // 'red'
---
layout: false
class: center, middle, inverse
# Bad Parts
---
layout: true
template: default
### Bad Parts
---
# Arrays
Indices are free to go.
var arr = [1, 2, 3];
arr[999] = 0; // WTF
arr.length; // 1000
delete arr[1];
arr; // [1, undefined, 3];
???
Sletting må gjøres med splice(1,1) (fjern ett element fra posisjon 1)
---
# for (... in ...)
Properties from the `prototype` chain are looped as well.
var key;
for (key in obj) {
if (obj.hasOwnProperty(key)) {
// Property belongs to obj itself
}
}
---
# eval is evil
Property look-ups.
// Don't do
eval('var value = obj.' + key);
// Rather do
var value = obj[key];
Function references.
// Don't do
var f = new Function("alert('hello');");
setTimeout("alert('hello')", 1000);
setInterval("alert('hello')", 1000);
// Rather do
var f = function () { alert('hello'); };
setTimeout(f, 1000);
---
# Falsy values
- __`false`__
- __`null`__
- __`undefined`__
- `0` (zero)
- `''` or `""` (empty string)
- __`NaN`__ (not-a-number, e.g. 'a' / 2)
`&&` and `||` return the actual value of the expession that stops the evaluation:
function Car (name) {
this.name = name || 'default name';
}
---
# Transitivity - come again?
0 == '0' // true
0 == '' // true
'' == '0' // false
false == 'false' // false
false == '0' // true
undefined == false // false
undefined == true // false
false == null // false
null == undefined // true
' \t\r\n ' == 0 // true
---
# Semicolon insertion (1/2)
function getStatus () {
return
{
status: true
}
}
---
# Semicolon insertion (2/2)
function getStatus () {
return; <- semicolon insertion
{ <- open block
status: true <- loop label
} <- close block
}
# W T F
---
# arguments is not an array
It only pretends to be.
{
'0': 1,
'1': 2,
length: 2
}
But you can fix it.
function f () {
var slice = Array.prototype.slice; // [].slice
return slice.apply(arguments);
}
f(1, 2); // [1, 2]
---
# Keywords
obj[&lt;keyword&gt;] = 1 // Reserved word (undefined, NaN, Infinity?)
- `abstract`
- __`boolean`__ __`break`__ `byte`
- __`case`__ __`catch`__ `char` `class` `const` __`continue`__
- __`debugger`__ __`default`__ __`delete`__ `do` `double`
- __`else`__ `enum` `export` `extends`
- __`false`__ `final` __`finally`__ `float` __`for`__ __`function`__
- `goto`
- __`if`__ `implements` `import` __`in`__ __`instanceof`__ `int` `interface`
- `long`
- `native` __`new`__ __`null`__
- `package` `private` `protected` `public`
- __`return`__
- `short` `static` `super` __`switch`__ `synchronized`
- __`this`__ __`throw`__ `throws` `transient` __`true`__ __`try`__ __`typeof`__
- __`var`__ `volatile` __`void`__
- __`while`__ __`with`__
---
# Avoid void
Void is not useful, avoid void!
- __`void`__ is an operator
- takes an operand
- returns __`undefined`__
` `
void 1 // undefined
---
layout: false
class: center, middle, inverse
# That's all folks!
Slideshow created with [remark](http://gnab.github.com/remark).
</textarea>
<script>
var slideshow = remark.create({ highlightLanguage: 'javascript'});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment