js> {} + []
0
js> {}
js> + []
0
js> + ''
0
js> ({} + [])
"[object Object]"
js> {} + {}
NaN
js> {}
js> + {}
NaN
js> + '[object Object]'
NaN
js> ({} + {})
"[object Object][object Object]"
js> Array(16).join()
",,,,,,,,,,,,,,,"
js> Array(16).join().length
15
js> 'wat' - 1
NaN
(JS evolves along with the rest of the web standards)
Official goals: a better language for
Official goals: a better language for
class SkinnedMesh extends THREE.Mesh {
constructor(geometry, materials) {
super(geometry, materials);
this.identityMatrix = new THREE.Matrix4();
this.bones = [];
this.boneMatrices = [];
...
}
update(camera) {
...
super.update();
}
}
function SkinnedMesh(geometry, materials) {
SkinnedMesh.__super__.constructor
.call(this, geometry, materials);
this.identityMatrix = new THREE.Matrix4();
this.bones = [];
this.boneMatrices = [];
...
}
__extends(SkinnedMesh, THREE.Mesh)
SkinnedMesh.prototype.update = function (camera) {
...
SkinnedMesh.__super__.update.call(this);
}
module FastMath {
export function sin() { /*...*/ }
export function cos() { /*...*/ }
}
import {sin, cos} from FastMath;
import $ from "http://js.com/jquery/1.8.1/jquery-min.js";
const cloneSym = new Symbol();
// Symbol names are guaranteed not to collide
Object.defineProperty(Object.prototype, cloneSym, {
value: function () {
// universal cloning code unobtainium here
}
});
var twin = obj[cloneSym]();
module Branding {
const brandSym = new Symbol(); // not exported
export function brand(obj, mark) {
if (!obj.hasOwnProperty(brandSym))
obj[brandSym] = mark;
}
export function hasBrand(obj, mark) {
return obj[brandSym] === mark;
}
}
public @clone;
Object.defineProperty(Object.prototype, @clone, {
value: function () {
// universal cloning code unobtainium here
}
});
var twin = obj.@clone();
module Branding {
private @brand; // not exported
export function brand(obj, mark) {
if (!obj.hasOwnProperty(@brand))
obj.@brand = mark;
}
export function hasBrand(obj, mark) {
return obj.@brand === mark;
}
}
class SkinnedMesh extends THREE.Mesh {
private @identityMatrix,
@bones,
@boneMatrices;
constructor(geometry, materials) {
super(geometry, materials);
this.@identityMatrix = new THREE.Matrix4();
this.@bones = [];
this.@boneMatrices = [];
...
}
...
}
// Internal string name, for debugging and diagnostics
const myPublicSymbol = new Symbol("my public symbol");
// Binding initializers for renaming and full control
private @score = importedSharedSecrets.@score;
js> function f(a = 0, b = a * a, c = b * a) {
return [a, b, c];
}
js> f()
[0, 0, 0]
js> f(2)
[2, 4, 8]
js> f(2, 3)
[2, 3, 6]
js> f(2, 3, 4)
[2, 3, 4]
js> function f(a, b, ...r) {
print(Array.isArray(r));
return r.concat(a, b);
}
js> f(1, 2)
true
[1, 2]
js> f(1, 2, 3)
true
[3, 1, 2]
js> f(1, 2, 3, 4, 5)
true
[3, 4, 5, 1, 2]
js> a = [3, 4, 5]
[3, 4, 5]
js> b = [1, 2, ...a]
[1, 2, 3, 4, 5]
js> function f(...r) { return r; }
js> function g(a) { return f(...a); }
js> g(a)
[3, 4, 5]
for-of
, Iterators & Generators
js> for (var v of [1, 2, 3]) {
print(v)
}
1
2
3
js> for (var [k, v] of {p: 3, q: 4, r: 5}) {
print(k, v)
}
typein:24:0 TypeError: ({p:3, q:4, r:5}) is not iterable
js> Object.defineProperty(Object.prototype, @iterator, {
value: function () {
var obj = this;
var keys = Object.keys(obj);
var i = 0;
return {
next: function () {
if (i == keys.length) throw StopIteration;
var key = keys[i++];
return [key, obj[key]];
}
};
}
});
js> for (var [k, v] of {p:3, q: 4, r: 5}) print(k, v);
p 3
q 4
r 5
js> function* items(o) { // in ES6 standard library
for (var k in o) {
yield [k, o[k]];
}
}
js> for (var [k, v] of items({p:3, q: 4, r: 5})) {
print(k, v);
}
p 3
q 4
r 5
js> Object.defineProperty(Object.prototype, @iterator, {
value: items
});
js> for (var [k, v] of {p:3, q: 4, r: 5}) print(k, v);
p 3
q 4
r 5
load("config.json",
function(config) {
db.lookup(JSON.parse(config).table, username,
function(user) {
load(user.id + ".png", function(avatar) {
// <-- you could fit a cow in there!
});
}
);
}
);
load("config.json")
.then(function(config) {
return db.lookup(JSON.parse(config).table);
})
.then(function(user) { return load(user.id + ".png"); })
.then(function(avatar) { /* ... */ });
import spawn from "http://taskjs.org/es6-modules/task.js";
spawn(function* () {
var config = JSON.parse(yield load("config.json"));
var user = yield db.lookup(config.table, username);
var avatar = yield load(user.id + ".png");
// ...
});
// Using depth-first search and constraint propagation,
// try all possible values.
function search(values) {
if (!values)
return false; // Failed earlier
if (all(values[s].length == 1 for (s of squares)))
return values; // Solved!
// Choose unfilled square s with fewest possibilities
let a = [values[s].length + s for (s of squares)
if (values[s].length > 1)]
.sort();
let s = a[0].slice(-2);
return some(search(assign(values.copy(), s, d))
for (d of values[s]));
}
js> var objkey1 = {toString: function(){return "objkey1"}}
js> var objkey2 = {toString: function(){return "objkey2"}}
js>
js> var map = Map([[objkey1, 42], [objkey2, true]])
js> map.get(objkey1)
42
js> map.get(objkey2)
true
js> assert(!map.has("objkey1") && !map.has("objkey2"))
js> map.set(objkey1, 43)
js> map.get(objkey1)
43
js> map.set("stringkey", "44!")
js> for (var [k, v] of map) {
print(k, v)
}
objkey1 43
objkey2 true
stringkey 44!
js> map.size()
3
js> map.set(objkey2, objkey1)
js> map.set(objkey1, objkey2)
js> for (var [k, v] of map) {
print(k, v)
}
objkey1 objkey2
objkey2 objkey1
stringkey 44!
js> map.delete(objkey1)
true
js> map.delete(objkey2)
true
js> for (var [k, v] of map) {
print(k, v)
}
stringkey 44!
js> map.size()
1
js> var set = Set([1, true, "three"])
js> set.has(1)
true
js> set.has(2)
false
js> for (var e of set) {
print(e)
}
1
true
three
js> set.size()
3
js> set.delete("three")
true
js> for (var e of set) {
print(e)
}
1
true
js> set.size()
2
js> set.add("three")
js> set.size()
3
js> var four = {toString: function(){return '4!'}}
js> set.add(four)
js> set.has(four)
true
js> for (var e of set) {
print(e)
}
1
true
three
4!
js> var wm = WeakMap()
js> wm.set(objkey1, objkey2)
js> wm.set(objkey2, objkey1)
js> wm.has(objkey1)
true
js> wm.get(objkey1)
({toString:(function (){return "objkey2"})})
js> wm.has(objkey2)
true
js> wm.get(objkey2)
({toString:(function () {return 'objkey1'})})
js> gc()
"before 286720, after 282720\n"
js> objkey1 = null
null
js> wm.get(objkey2)
({toString:(function () {return 'objkey1'})})
js> objkey2 = null
null
js> gc()
"before 286720, after 282624\n"
js> var MethodSink = Proxy({}, {
has: function(target, name) { return true; },
get: function(target, name, receiver) {
if (name in Object.prototype) {
return Object.prototype[name];
}
return function(...args) {
return receiver.__noSuchMethod__(name, args);
}
}
});
js> Object.defineProperty(
Object.prototype,
'__noSuchMethod__',
{
configurable: true,
writable: true,
value: function(name, args) {
throw new TypeError(name + " is not a function");
}
}
);
js> var obj = {
foo: 1 ,
__proto__: MethodSink,
__noSuchMethod__: function(name, args) {
return name;
}
}
js> obj.foo
1
js> obj.bar()
"bar"
js> obj.toString
function toString() {
[native code]
}
js> obj.bar
(function (...args) {
return receiver.__noSuchMethod__(name, args);
})
js> var thunk = obj.bar
js> thunk()
"bar"
Official goals: a better language for
We had always thought that Java's JVM would be the VM of the web, but it turns out that it's JavaScript. JavaScript's parser does a more efficient job... than the JVM's bytecode verifier.
function f() {
L0:
g();
L1:
if (p)
goto L0;
o.m();
goto L1;
}
function f() {
function L0() {
g();
return L1(); // goto with arguments
}
function L1() {
if (p)
return L0(); // goto with arguments
o.m();
return L0(); // goto with arguments
}
return L0(); // goto with arguments
}
function void swap(int *a, int *b) {
let int tmp = *a;
*a = *b;
*b = tmp;
}
let int x = 1, y = 2;
swap(&x, &y);
console.log(x, y);
class AbstractSingletonProxyFactoryBean {
/** @type Object It's an object! */
private Object bean;
}
var a = new Uint32Array(1024);
for (var i = 0, n = a.length; i < n; i++) {
a[i] = i * i;
}
// a user-defined type
var Point = struct({
x: uint32,
y: uint32
});
var origin = new Point(0, 0);
console.log(origin.x); // 0
console.log(origin.y); // 0
macro def {
case $name:ident $params $body => {
function $name $params $body
}
}
def sweet(a) {
console.log("Macros are sweet!");
}
pixelData.map(toGrayScale)
.map(function(color) {
return [color,color,color,255]; // new pixel
})
var tasks = rows.map(function(row, i) {
return fork(render, [row, i]); // fork a subtask
});
oncompletion(function() {
var images = tasks.map(function(task) {
return task.get(); // get subtask result
});
display(images);
});