JS är ett dynamiskt, svagt typat språk, vilket innebär att många skyddsnät som man är van vid när man använder ett statisk, starkt typat språk, som exv C#, inte finns.
Detta ställer höga krav på utvecklaren att skriva tydlig kod samt att implementera tillräckligt med felhantering och/eller kollar för att vara säker på att värden finns och är av rätt underliggande typ innan man använder dem.
Väldigt stor skillnad på vad man har tillgängligt beroende på vilken specifikation man bestämmer sig för att använda. Dagens webbläsare har kommit långt i att implementera moderna (läs ES2015) features, men man kan inte vara säker på att de har stöd för allt. Därför väljer man oftast i nya projekt att kompilera sin kod mot ES5, som det finns stöd för ända ned till IE9.
https://caniuse.com är en bra resurs för att se vilka API:r och vilka språkstöd det finns i olika runtimes.
TypeScript är ett starkare typat språk som är väldigt likt JavaScript i övrigt, men är en egen "kurs".
a.js:
var a = 1;
b.js:
console.log(a);
--
c.js:
function doNastyStuff() {
c = 99;
}
doNastyStuff();
d.js:
console.log(c);
SP är fullt av detta.
// Lexical & block scope
var varInBlockScope = function () {
var throws = function () {
try {
console.log('This is not gonna happen', undefVar);
} catch (e) {
console.log('From throws', e);
}
};
var ok = function () {
console.log('From ok', a);
if (false) {
var a = 1;
}
};
throws();
ok();
};
undefined
vs null
vs 0
vs 1
vs []
vs {}
etc.
sanningstabell för när ==
används
http://i.stack.imgur.com/5bdbd.png
a.k.a. strict equality
-- ALWAYS.
ASI och mental börda.
function func() {
return 'a string';
}
func()
(function () {
console.log('IIFE');
})();
var n = 1;
function printSomething() {
console.log(n);
var n = 2;
console.log(n);
}
while(true) {} // haha, your browser froze
- "non-blocking"
jmf
var v1 = 1;
var v2 = function () {
return 1;
};
vänta på något:
funciton doSomethingWchichIsAsynchronouslyExecuted(callback) {
setTimeout(function () {
callback();
}, 1000);
}
doSomethingWchichIsAsynchronouslyExecuted(function whenDoneCallMe() {
console.log('done');
});
Error
s
stack trace
throw
& try
/catch
try {
throw new Error();
} catch (Exception e) {
console.error(e);
}
function mutateValueFails(v) {
v = 99;
}
var array = [11, 22, 33, 44];
for (var i = 0; i < array.length; ++i) {
mutateValueFails(array[i]);
}
console.log(array);
function mutateValueSucceeds(a, i) {
a[i] = 99;
}
for (var i = 0; i < array.length; ++i) {
mutateValueSucceeds(array, i);
}
console.log(array);
closure:
var getAValueGetter = function () {
var val = 'value';
return function () {
return val;
};
};
var valueGetter = getAValueGetter();
var value = valueGetter();
this
:
var person = {
name: 'Björn',
shout: function (what) {
console.log(this.name, 'shouts', what.toUpperCase());
}
}
console.log(person.shout('javascript is crazy'));
function ConstructorFn(value) {
this.value = value;
}
var instance = new ConstructorFn('test');
console.log(instance);
bind, call and apply
var a = {
name: 'adam' // ett av mina mellannamn, FYI
};
var b = {
name: 'björn'
};
function greet(greeting) {
console.log(greeting, this.name, '!');
}
greet.call(a, 'hi');
greet.call(b, 'hello');
greet.apply(a, [ 'hi' ]);
greet.apply(b, [ 'hello' ]);
var greetA = greet.bind(a, 'salutations');
var greetB = greet.bind(b, 'wzup');
greetA();
greetB();
funktioner med sido-effekter
funktioner utan sido-effekter idempotenta funktioner rena funktioner
värdet av idempotenta funktioner
- memoisering
- enklare att resonera kring och testa än funktioner med sido-effekter.
värdet av rena funktioner
- inkluderar fördelar med idempotenta funktioner samt
- är ännu enklare att resonera kring.
typeof
instanceof
.prototype
och prototypkedjan samt new
filter, map, reduce (, forEach)
var a = ['a', 'b', 'c', 'd', 'e', 'f'];
console
-
Chrome DevTools
-
IE Developer Toolbar
-
detektivarbete
-
debugging