Instructor: Stefan Mitsch
fixed
1 + 2
undefined result
console.log (1 + 2);
return statements
function f (x) {
console.log ("Called with " + x);
return x + 1;
}
f (5);
skeleton.html
and skeleton.js
skeleton.html in browser
body:
<input id="a" type="text" value="empty"/>
<div id="b"/><p>Hi Mom</p></div>
<div id="c"/><p>Hi Dad</p></div>
function main () {
var count = 0;
var a = document.querySelector('input#a');
var b = document.querySelector('div#b');
var c = document.querySelector('div#c');
for (var x of [b,c]) {
x.onclick = function (e) {
e.target.outerHTML += "<p>Again! " + count++ + "</p>";
} }
a.value = 1 + 2;
c.innerHTML += "<p>I love teletubbies!</p>";
}
document.addEventListener("DOMContentLoaded", main);
[] + [] /* '' */
[] + {} /* [object Object] */
{} + [] /* VS8: 0, Node.js: [object Object] */
{} + {} /* VS8: NaN, Node.js: [object Object][object Object] */
xs = ["10", "10", "10"];
xs.map(parseInt) /* [10, NaN, 2] */
[1,5,20,10].sort() /* [1, 10, 20, 5] */
undefined + 1 /* NaN */
false + 1 /* 1 (someone liked C) */
5/0 /* Infinity */
-1/0 /* -Infinity */
'' == '0'
0 == ''
0 == '0'
10 == '10'
9 == '9'
10 > 9
'10' > '9'
1 + 9
1 + '9'
1 + '9' == 19
-1 + '11'
'11' - 1
false == 'false'
false == ''
false == '0'
false == 0
true == '1'
true > false
5/0 == 6/0
0/0 == 0/0
1/0 == -1/0
/* floats suck (as usual) */
1/10000000000000000000000 /* 1e-22 */
1/100000000000000000000000 /* 1.0000000000000001e-23 */
1/10000000000000000000000000 /* 9.999999999999999e-26 */
1/1000000000000000000000000000 /* 1e-27 */
false == undefined
false == null
null == undefined
Infinity == Infinity
NaN == NaN
' \t\r\n ' == 0
'' == '0' /* false */
0 == '' /* true */
0 == '0' /* true */
10 == '10' /* true */
9 == '9' /* true */
10 > 9 /* true */
'10' > '9' /* false */
1 + 9 /* 10 */
1 + '9' /* '19' */
1 + '9' == 19 /* true */
-1 + '11' /* '-111' */
'11' - 1 /* 10 */
false == 'false' /* false */
false == '' /* true */
false == '0' /* true */
false == 0 /* true */
true == '1' /* true */
true > false /* true */
5/0 == 6/0 /* true: x/0 is Infinity for x>0 */
0/0 == 0/0 /* false: 0/0 is NaN */
1/0 == -1/0 /* false: x/0 is -Infinity for x<0 */
/* floats suck (as usual) */
1/10000000000000000000000 /* 1e-22 */
1/100000000000000000000000 /* 1.0000000000000001e-23 */
1/10000000000000000000000000 /* 9.999999999999999e-26 */
1/1000000000000000000000000000 /* 1e-27 */
false == undefined /* false */
false == null /* false */
null == undefined /* true */
Infinity == Infinity /* true */
NaN == NaN /* false */
' \t\r\n ' == 0 /* true */
Use ===, which does no conversions
var a = 1;
function f () {
console.log ("f1: a = " + a);
{ var a = 2;
console.log ("f2: a = " + a);
} }
function main() {
console.log ("m1: a = " + a);
f ();
console.log ("m2: a = " + a);
}
m1: a = 1
f1: a = undefined
f2: a = 2
m2: a = 1
var a = 1;
function f () {
var a; /* = undefined */
console.log ("f1: a = " + a);
{ a = 2;
console.log ("f2: a = " + a);
} }
function main() {
console.log ("m1: a = " + a);
f ();
console.log ("m2: a = " + a);
}
m1: a = 1
f1: a = undefined
f2: a = 2
m2: a = 1
let
var a = 1;
function f () {
console.log ("f1: a = " + a);
{ let a = 2;
console.log ("f2: a = " + a);
} }
function main() {
console.log ("m1: a = " + a);
f ();
console.log ("m2: a = " + a);
}
m1: a = 1
f1: a = 1
f2: a = 2
m2: a = 1
var a = 1;
function f (b) {
a = 2;
if (b) {
var a;
a = a + 1;
}
console.log (" f: a = " + a);
}
function main() {
f (true);
console.log ("m1: a = " + a);
f (false);
console.log ("m2: a = " + a);
}
f: a = 3
m1: a = 1
f: a = 2
m2: a = 1
function fibtail(n) {
function fibtail(n, r1, r2) { // nested function, inner n shadows outer n
if (n===0) return r1;
else if (n===1) return r2;
else return fibtail(n-1, r2, r1+r2);
}
return fibtail(n, 0, 1);
}
function swaparray(a) {
let [x,y] = a; // deconstruct array
a[0] = y;
a[1] = x;
}
let a = [x, y];
swaparray(a);
{
[y,x] = [x,y]; // deconstruct array to swap in place
}
var xs = [ 11, 21, 31 ];
xs.map (x => (2 * x));
xs.filter (x => x%7===0)
xs.reduce (((z,x) => z+x), 0)
javac requires final i from enclosing scope
for (int i = 0; i < 5; i++) { /* rejected: i mutates */
new Thread (new Runnable () {
public void run () {
while (true) { System.out.print (i); }
}
}).start ();
}
for (int i = 0; i < 5; i++) {
int x = i; /* accepted: x never mutates */
new Thread (new Runnable () {
public void run () {
while (true) { System.out.print (x); }
}
}).start ();
}
var funcs = [];
for (var i = 0; i < 5; i++) {
funcs.push (function () { return i; });
}
funcs.map (f => f());
[ 5, 5, 5, 5, 5 ]
i?
var funcs = [];
var x;
for (var i = 0; i < 5; i++) {
x = i; /* x is shared too! */
funcs.push (function () { return x; });
}
funcs.map (f => f());
[ 4, 4, 4, 4, 4 ]
var is not block scope
var funcs = [];
for (var i = 0; i < 5; i++) {
var x = i; /* x is still shared! */
funcs.push (function () { return x; });
}
funcs.map (f => f());
[ 4, 4, 4, 4, 4 ]
let
var funcs = [];
for (var i = 0; i < 5; i++) {
let x = i; /* block scope */
funcs.push (function () { return x; });
}
funcs.map (f => f());
[ 0, 1, 2, 3, 4 ]
var funcs = [];
for (var i = 0; i < 5; i++) {
(function () {
var x = i;
funcs.push (function () { return x; });
}) ();
}
funcs.map (f => f());
[ 0, 1, 2, 3, 4 ]
var funcs = [];
for (var i = 0; i < 5; i++) {
var help = function (x) {
return function () { return x; }
};
funcs.push (help (i));
}
funcs.map (f => f());
[ 0, 1, 2, 3, 4 ]
$
_