Instructor: James Riely
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] */
{} + [] /* 0 */
{} + {} /* NaN */
xs = ["10", "10", "10"];
xs.map(parseInt) /* [10, NaN, 2] */
[1,5,20,10].sort() /* [1, 10, 20, 5] */
undefined + 1 /* NaN */
'' == '0' /* false */
0 == '' /* true */
0 == '0' /* true */
false == 'false' /* false */
false == '0' /* true */
false == undefined /* false */
false == null /* false */
null == undefined /* true */
' \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
var a = 1;
{
let b = a + 1;
let a = 2;
console.log (" b = " + b);
}
Uncaught ReferenceError: Cannot access 'a' before initialization
val a = 1;
{
val b = a + 1;
val a = 2;
println (" b = " + b);
}
3 | val b = a + 1;
| ^
| a is a forward reference extending over the definition of b
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 ]
$
_