http://mbranko.github.io/webkurs
Ovo je deo web kursa
this
sa kodom koji je okružujehttps://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions
// Expression bodies
var odds = evens.map(v => v + 1);
var nums = evens.map((v, i) => v + i);
var pairs = evens.map(v => ({even: v, odd: v + 1}));
// Statement bodies
nums.forEach(v => {
if (v % 5 === 0)
fives.push(v);
});
// Lexical this
var bob = {
_name: "Bob",
_friends: [],
printFriends() {
this._friends.forEach(f =>
console.log(this._name + " knows " + f));
}
}
super
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes
class SkinnedMesh extends THREE.Mesh {
constructor(geometry, materials) {
super(geometry, materials);
this.idMatrix = SkinnedMesh.defaultMatrix();
this.bones = [];
this.boneMatrices = [];
//...
}
update(camera) {
//...
super.update();
}
get boneCount() {
return this.bones.length;
}
set matrixType(matrixType) {
this.idMatrix = SkinnedMesh[matrixType]();
}
static defaultMatrix() {
return new THREE.Matrix4();
}
}
foo: foo
dodelasuper
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Object_literals
var obj = {
// __proto__
__proto__: theProtoObj,
// Shorthand for ‘handler: handler’
handler,
// Methods
toString() {
// Super calls
return "d " + super.toString();
},
// Computed (dynamic) property names
[ 'prop_' + (() => 42)() ]: 42
};
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings
// Basic literal string creation
`In JavaScript '\n' is a line-feed.`
// Multiline strings
`In JavaScript this is
not legal.`
// String interpolation
var name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?`
// Construct an HTTP request
// prefix is used to interpret the replacements and construction
POST`http://foo.org/bar?a=${a}&b=${b}
Content-Type: application/json
X-Credentials: ${credentials}
{ "foo": ${foo},
"bar": ${bar}}`(myOnReadyStateChangeHandler);
undefined
za ono što ne pronađehttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
// raspakivanje liste
var [a, , b] = [1,2,3];
// raspakivanje objekta
var { op: a, lhs: { op: b }, rhs: c }
= getASTNode()
// raspakivanje objekta, uz skraćeno pisanje
var {op, lhs, rhs} = getASTNode()
// može se koristiti i kod navođenja parametara
function g({name: x}) {
console.log(x);
}
g({name: 5})
// Fail-soft: ono što ne pronađe biće undefined
var [a] = [];
a === undefined;
// Fail-soft sa default vrednostima
var [a = 1] = [];
a === 1;
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator
// default
function f(x, y=12) {
// y je 12 ako se ne prosledi (ili se prosledi undefined)
return x + y;
}
f(3) == 15
// rest
function f(x, ...y) {
// y je Array
return x * y.length;
}
f(3, "hello", true) == 6
// spread
function f(x, y, z) {
return x + y + z;
}
// prosledi elemente niza kao pojedinačne parametre
f(...[1,2,3]) == 6
let
: deklaracija promenljiveconst
: deklaracija konstante
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const
function f() {
{
let x;
{
// ovo je OK, u ovom bloku x je novo ime
const x = "sneaky";
// greška, x je konstanta
x = "foo";
}
// greška, već deklarisano u ovom bloku
let x = "inner";
}
}
Iterable
ili .NET IEnumerable
for..of
je petlja za iteraciju kroz iteratorhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of
let fibonacci = {
[Symbol.iterator]() {
let pre = 0, cur = 1;
return {
next() {
[pre, cur] = [cur, pre + cur];
return { done: false, value: cur }
}
}
}
}
for (var n of fibonacci) {
// preseci sekvencu na 1000
if (n > 1000)
break;
console.log(n);
}
Iteracija je zasnovana na ovim interfejsima; dovoljan je duck-typing.
interface IteratorResult {
done: boolean;
value: any;
}
interface Iterator {
next(): IteratorResult;
}
interface Iterable {
[Symbol.iterator](): Iterator
}
Interfejsi definisani pomoću TypeScript-a.
function*
vraća generatornext
i throw
yield
je izraz koji vraća (deo) rezultatahttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols
var fibonacci = {
[Symbol.iterator]: function*() {
var pre = 0, cur = 1;
for (;;) {
var temp = pre;
pre = cur;
cur += temp;
yield cur;
}
}
}
for (var n of fibonacci) {
// preseci sekvencu na 1000
if (n > 1000)
break;
console.log(n);
}
Interfejs generatora je:
interface Generator extends Iterator {
next(value?: any): IteratorResult;
throw(exception: any);
}
Interfejs definisan pomoću TypeScript-a.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/unicode
// isto kao kod ES5.1
"𠮷".length == 2
// novi regexp, specijalni kod 'u'
"𠮷".match(/./u)[0].length == 2
// novi oblik
"\u{20BB7}"=="𠮷"=="\uD842\uDFB7"
// nove String funkcije
"𠮷".codePointAt(0) == 0x20BB7
// for...of prolazi kroz code points
for(var c of "𠮷") {
console.log(c);
}
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export
// lib/math.js
export function sum(x, y) {
return x + y;
}
export var pi = 3.141593;
// app.js
import * as math from "lib/math";
alert("2π = " + math.sum(math.pi, math.pi));
// otherApp.js
import {sum, pi} from "lib/math";
alert("2π = " + sum(pi, pi));
// lib/mathplusplus.js
export * from "lib/math";
export var e = 2.71828182846;
export default function(x) {
return Math.log(x);
}
// app.js
// ln je default exported
import ln, {pi, e} from "lib/mathplusplus";
alert("2π = " + ln(e)*pi*2);
// dinamičko učitavanje – 'System' je default loader
System.import('lib/math').then(function(m) {
alert("2π = " + m.sum(m.pi, m.pi));
});
// izolovano izvršavanje - novi punjači
var loader = new Loader({
global: fixup(window) // zameni console.log
});
loader.eval("console.log('hello world!');");
// direktna manipulacija kešom modula
System.get('jquery');
System.set('jquery', Module({$: $}));
Map
, Set
: uobičajene strukture podataka
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet
// Set
var s = new Set();
s.add("hello").add("goodbye").add("hello");
s.size === 2;
s.has("hello") === true;
// Map
var m = new Map();
m.set("hello", 42);
m.set(s, 34);
m.get(s) == 34;
// WeakMap
var wm = new WeakMap();
wm.set(s, { extra: 42 });
wm.size === undefined
// WeakSet
var ws = new WeakSet();
ws.add({ data: 42 });
// na dodati objekat nema drugih referenci => neće se čuvati u WeakSetu
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
// proxy ka objektu
var target = {};
var handler = {
get: function (receiver, name) {
return `Hello, ${name}!`;
}
};
var p = new Proxy(target, handler);
p.world === 'Hello, world!';
// proxy ka funkciji
var target = function () { return 'I am the target'; };
var handler = {
apply: function (receiver, ...args) {
return 'I am the proxy';
}
};
var p = new Proxy(target, handler);
p() === 'I am the proxy';
Postoji udica za sve meta-operacije u toku izvršavanja:
var handler =
{
get:...,
set:...,
has:...,
deleteProperty:...,
apply:...,
construct:...,
getOwnPropertyDescriptor:...,
defineProperty:...,
getPrototypeOf:...,
setPrototypeOf:...,
enumerate:...,
ownKeys:...,
preventExtensions:...,
isExtensible:...
}
Symbol
for...in
, for...of
i Object.getOwnPropertyNames
Object.getOwnPropertySymbols
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol
var sym1 = Symbol();
var sym2 = Symbol('foo'); // foo je opcioni opis simbola
var sym3 = Symbol('foo'); // opis je koristan (samo) za debugging
sym2 === sym3; // false
log.levels = {
DEBUG: Symbol('debug'),
INFO: Symbol('info'),
WARN: Symbol('warn'),
};
log(log.levels.DEBUG, 'debug message');
log(log.levels.INFO, 'info message');
var size = Symbol('size');
class Collection {
constructor() {
this[size] = 0;
}
add(item) {
this[this[size]] = item;
this[size]++;
}
static sizeOf(instance) {
return instance[size];
}
}
var x = new Collection();
assert(Collection.sizeOf(x) === 0);
x.add('foo');
assert(Collection.sizeOf(x) === 1);
assert.deepEqual(Object.keys(x), ['0']);
assert.deepEqual(Object.getOwnPropertyNames(x), ['0']);
assert.deepEqual(Object.getOwnPropertySymbols(x), [size]);
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
function timeout(duration = 0) {
return new Promise((resolve, reject) => {
setTimeout(resolve, duration);
})
}
var p = timeout(1000).then(() => {
return timeout(2000);
}).then(() => {
throw new Error("hmm");
}).catch(err => {
return Promise.all([timeout(100), timeout(200)]);
})
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect
function factorial(n, acc = 1) {
'use strict';
if (n <= 1)
return acc;
return factorial(n - 1, n * acc);
}
// stack overflow u većini implementacija,
// ali bezbedno u ES6
factorial(100000)