(with cool names)
HIDDEN GEMS
Boolean isOdd(int num) {
if(num == 2147483647) {
return true;
} else if (num == 0) {
return false;
}
return isOdd(num+=2);
}
Hidden gems from ES6
90'S STYLE!
Hidden gems from ES6...
smoothMove.js
export default makeSmooth(element) {
// magically make js
// do animation wow
// much awesome
}
export default makeSmooth(element) {
if(!element.isMoving) {
// do much magic wow
}
element.isMoving = true;
}
SYMBOL
SYMBOL
const a = Symbol();
const b = Symbol();
a == b // false
const a = Symbol('name');
console.log(a) // 'Symbol(name)'
log.levels = {
DEBUG: Symbol('debug'),
INFO: Symbol('info'),
WARN: Symbol('warn'),
};
log(log.levels.DEBUG, 'debug message');
log(log.levels.INFO, 'info message');
const isMoving = Symbol("isMoving");
...
if (element[isMoving]) {
// awesome smooth stuff
}
element[isMoving] = true;
const isMoving = Symbol("isMoving");
element[isMoving] = true;
element.isMoving = false;
element['isMoving'] = false;
element.<everythingPossible> = false;
element[isMoving] = true;
const cool = Symbol("Cool");
myObj[cool] = true;
Object.keys(myObj) // []
for(let key of myObj) {
console.log(key) // nothing
}
const secret = Symbol("Secret");
myObj[secret] = "Bitcoin Wallet";
const fakeSecret = Symbol("Secret");
myObj[fakeSecret] // undefined
myObj[Symbol("Secret")] //undefined
myObj[secret] // "Bitcoin Wallet"
const image = getImageFromServer();
JSON.stringify(image)
// { name: '..', size: '..' }
const EMPTY = Symbol('empty')
image[EMPTY] = !image.url;
JSON.stringify(image)
// { name: '..', size: '..' }
const empty = Symbol("empty");
const globalEmpty = Symbol.for("empty");
const globalEmpty2 = Symbol.for("empty");
empty == globalEmpty // false
globalEmpty == globalEmpty2 // true
Class FreshPrince {
constructor() {
this._innerArray = ['Will', 'Jazz'];
}
[Symbol.iterator]() {
return this._innerArray[Symbol.iterator]();
}
}
const prince = new FreshPrince();
for (let name of prince) {
console.log(name); // Will, Jazz
}
prince instanceOf Array // false
prince instanceOf FreshPrince // true
Class FreshPrince {
constructor() {
this._innerArray = ['Will', 'Jazz'];
}
}
Class FreshPrince {
constructor() {
this._innerArray = ['Will', 'Jazz'];
}
[Symbol.iterator]() {
return /* ??? */
}
}
Symbol.iterator
const prince = new FreshPrince();
for (let name of prince) {
console.log(name); // ???
}
Class Carlton {
constructor() {
this._height = '1.5';
}
[Symbol.toPrimitive]() {
return this._height;
}
}
const carlton = new Carlton();
carlton == '1.5' // true
let i = 0;
Class Wtf {
[Symbol.toPrimitive]() {
return i++;
}
}
const wtf = new Wtf ();
wtf == 0 && wtf == 1 && wtf == 2 // true
Symbol.toPrimitive
Symbol.iterator
Symbol.match
Symbol.replace
Symbol.toPrimitive
Symbol.hasInstance
uniqueArray = a.filter(function(item, pos, self) {
return self.indexOf(item) == pos;
})
function uniq(a) {
var seen = {};
return a.filter(function(item) {
return seen.hasOwnProperty(item) ? false : (seen[item] = true);
});
}
function uniq(a) {
var prims = {"boolean":{}, "number":{}, "string":{}}, objs = [];
return a.filter(function(item) {
var type = typeof item;
if(type in prims)
return prims[type].hasOwnProperty(item) ? false : (prims[type][item] = true);
else
return objs.indexOf(item) >= 0 ? false : objs.push(item);
});
}
1. Quickly find if an image is selected
2. Preserve order
3. No duplicates, of course
const selected = {};
const selectedOrdered = [];
function selectImage(img) {
selected[img.id] = true;
selectedOrdered.push(img.id);
}
function unselectImage(img) {
delete selected[img.id];
selectedOrdered = selectedOrdered.filter(id => id!==img.id);
}
const selected = {};
function selectImage(img) {
selected[img.id] = true;
}
function unselectImage(img) {
delete selected[img.id];
}
const set = new Set();
const set = new Set([1, 2, 3]);
const set = new Set(elementList);
const set = new Set(['Homer', 'Bart', 'Homer']);
set.size; // 2
const set = new Set();
set.add('Homer')
.add('Bart')
.add('Homer')
.add('Lisa');
for(let name of set){
console.log(name);
// 'Homer', 'Bart', 'Lisa'
}
new Set(...)
Set
const unique = [...new Set(arr)];
const lorem = 'ipsum';
function test() {
const a = myarr.map(()=> this.text != lorem.psium)
}
function removeUniques(arr) {
const removeUniques = () => arr.remove(this.unique !== this[i]);
this.tester.call();
}
const selected = new Set();
function selectImage(img) {
selected.add(img);
}
function unselectImage(img) {
selected.delete(img);
}
function isSelected(img){
return selected.has(img);
}
Oh, I'm in no condition to drive! Wait a minute. I don't have to listen to myself. I'm drunk.
I'll keep it short and sweet honey —
Family. Religion. Friendship. These are the three demons you must slay if you wish to succeed in business.
http://simpsons.dudaone.com/
you have a list of elements and you have to keep track on whos editing what
you have a list of elements and you have to keep track on whos editing what
const editedIds = {}
function setEdited(element, user) {
editedIds[element.id? element.name?] = user;
}
function whosEditing(element){
return editedIds[element.id?];
}
const map = new Map();
const map = new Map([
["Kids", 3],
["Why You Little", 10],
["Flanders", "Stupid"]
]);
const map = new Map(Object.entries({
name: "name",
age: 32
}));
new Map(...)
Map
const map = new Map();
map.set(user1, 'ADMIN');
map.set(user2, 'USER');
map.get(user1) // 'ADMIN'
map.set('100', 'str');
map.set(100, 'num');
map.get('100') // 'test'
map.get(100) // 'num'
Map
let recipeMap = new Map([
[{name: 'cucumber'}, 500],
[{name: 'tomatoes'}, 350],
[{name: 'onion'}, 50]
]);
// keys
for (let vegetable of recipeMap.keys()) {
console.log(vegetable); // {cucumber}, {tomatoes}, {onion}
}
// values
for (let amount of recipeMap.values()) {
console.log(amount); // 500, 350, 50
}
// entries
for (let [vegetable, amount] of recipeMap.entries()) {...}
Oh, I'm in no condition to drive! Wait a minute. I don't have to listen to myself. I'm drunk!
I'll keep it short and sweet honey —
Family. Religion. Friendship. These are the three demons you must slay if you wish to succeed in business.
http://simpsons.dudaone.com/
const editedElements = new Map();
function markEdited(element, user) {
editedElements.set(element) = user;
}
function whosEditing(element){
return editedElements.get(element);
}
function howManyEdited(){
return editedElements.size;
}
Oh, I'm in no condition to drive! Wait a minute. I don't have to listen to myself. I'm drunk!
I'll keep it short and sweet honey —
Family. Religion. Friendship. These are the three demons you must slay if you wish to succeed in business.
http://simpsons.dudaone.com/
I'll keep it short and sweet honey —
Family. Religion. Friendship. These are the three demons you must slay if you wish to succeed in business.
editedMap
const loggedUsers = new WeakSet();
let user = { name: 'Bart' }
let user2 = { name: 'Lisa'}
loggedUsers.add(user).add(user2);
delete user;
const editedElements = new WeakMap();
editedElements.set(element1, data1);
editedElements.set(element2, data2);
element1.remove();
Oh, I'm in no condition to drive! Wait a minute. I don't have to listen to myself. I'm drunk!
I'll keep it short and sweet honey —
Family. Religion. Friendship. These are the three demons you must slay if you wish to succeed in business.
http://simpsons.dudaone.com/
I'll keep it short and sweet honey —
Family. Religion. Friendship. These are the three demons you must slay if you wish to succeed in business.
editedWeakMap
function getSecret() {
const secrets = new WeakMap();
const myKey = {/* some obj */};
secrets.set(myKey, 'My Bitcoin Wallet');
return secrets;
}
const secrets = getSecret();
// no way to get the value!
Go get Nike 39
There are no Nikes
Go get Adidas 39
There are no Adidas
Go get Keds 39
Keds, but not 39
Go get Keds 38.5
Go get Nike 39
No Nike!
Get
Adidas!
No Adidas!
Get
Keds!
No size 39!
Get
38.5!
function getNames() {
const value1 = 'Bud';
while(veryLongTime) {
...
}
const value2 = 'Kelly';
return [value1, value2];
}
let names;
names = getNames();
console.log(names[0]);
// unrelated stuff
// ...
console.log(names[1]);
yield
function *namesGen() {
let i = 0;
yield 'Bud';
i++;
yield 'Kelly';
i++;
return i;
}
let names;
names = namesGen();
// ... some stuff
console.log(names.next().value);
// ... some more stuff
console.log(names.next().value);
// ... do things
console.log(names.next().value);
// 'Bud'
// 'Kelly'
// 2
function *tvShows() {
yield 'Psycho Dad';
yield 'Psycho Dad 2';
return 'Psycho Dad 3';
}
const tv = tvShows();
tv.next() // { value: 'Psycho Dad', done: false }
tv.next() // { value: 'Psycho Dad 2', done: false }
tv.next() // { value: 'Psycho Dad 3', done: true }
const tv = tvShows();
const tv = tvShows();
tv.next() // { value: 'Psycho Dad', done: false }
const tv = tvShows();
tv.next() // { value: 'Psycho Dad', done: false }
tv.next() // { value: 'Psycho Dad 2', done: false }
function *fiboGen() {
let a = 0;
let b = 1;
while(true) {
yield b;
[a, b] = [b, a + b];
}
}
const f = fiboGen();
console.log(f.next().value);
console.log(f.next().value);
onClick(() => {
console.log(f.next().value);
});
function *processTree(data){
if (!data) { return; }
for (var i = 0; i < data.length; i++) {
var val = data[i];
yield(val);
yield *processTree(val.children);
}
}
const data = processTree(tree);
let item = data.next();
while(!item.done){
console.log(item.value.id);
item = data.next();
}
1
1.1
1.2
1.3
1.2.1
2
2.1
1.2.2
function *processTree(data){
if (!data) { return; }
for (var i = 0; i < data.length; i++) {
var val = data[i];
yield(val);
yield *processTree(val.children);
}
}
N
O
M
A
A
M
!
'
const data = processTree(tree);
let item = data.next();
while(!item.done){
console.log(item.value.id);
item = data.next();
}
function *easyBlackJack(){
let result = 0;
let oneMore = true;
while(oneMore) {
let card = Math.random(10);
result += card;
if(result <= 21) {
oneMore = yield card;
} else {
return `${card}...Bummer.`;
}
}
return `You got a total of ${result}`;
}
const game = easyBlackJack();
let card = ebj.next();
while(!card.done) {
const hitMe = card.value < 9;
card = game.next(hitMe);
}
console.log(card.value)
7
true
3
true
9
false
19 total
function *promisesGenerator(){
const name = yield getNameFromServer();
let age;
if(name) {
age = yield getAgeFromServer(name);
}
return [name, age];
}
const p = promisesGenerator();
const namePromise = p.next().value;
const agePromise = namePromise.then(name => p.next(name).value);
const resultPromise = agePromise.then(age => p.next(age).value);
resultPromise.then(result => console.log(result));
function *promisesGenerator(){
const name = yield getNameFromServer();
let age;
if(name) {
age = yield getAgeFromServer(name);
}
return [name, age];
}
async function promisesGenerator(){
const name = await getNameFromServer();
let age;
if(name) {
age = await getAgeFromServer(name);
}
return [name, age];
}
A Long long time ago
const myObj = {};
Object.defineProperty(myObj, 'name', {
get: function(key){
console.log('Name was called');
return 'Chanandler Bong';
}
});
var x = myObj.name; // Name was called
console.log(x); // Chanandler Bong
const myObj = {};
Object.defineProperty(myObj, 'name', {
get: function(key){
return this._name;
},
set: function(key, value) {
this._name = 'Ms. ' + value;
}
});
myObj.name = 'Chanandler Bong';
console.log(myObj.name); // Ms. Chanandler Bong
Object.defineProperty
const friends = { Joey, Chandler, Rachel };
Object.seal(friends);
friends.Ross = 'Ross'; // Exception - cannot add to a sealed object
friends.Rachel = 'Monica'; // ok
const friends2 = Object.freeze(friends);
friends2.Chandler = 'Let it go'; // Exception - cannot change a frozen object
Object.seal/freeze
const friends = { Joey, Chandler, Rachel };
Object.seal(friends);
friends.Ross = 'Ross'; // Exception - cannot add to a sealed object
friends.Rachel = 'Monica'; // ok
Pretty lame.
But now....
PROXIES!!!
const originalObject = { name: 'Gunther' };
const handler = {};
const proxiedObject = new Proxy(originalObject, handler);
proxiedObject.name // Gunther
proxiedObject.age = 55;
proxiedObject.age // 55
const handler = {
get: function(target, key) {
// called when any property is accessed
},
set: function(target, key, value) {
// called when any property is changed
},
has: function(target, key) {
// called when checking (key in target)
},
deleteProperty: function(target, key) {
// called when any property is deleted
},
apply: function(target, thisArg, args) {
// called when the object is invoked as a function
}
};
const handler = {
get: function(target, key){
return Reflect.get(target, key) || 'No such friend';
}
};
const friends = new Proxy({}, handler);
console.log(proxiedObject.rachel) // 'No such friend'
proxiedObject.rachel = 'Rachel';
console.log(proxiedObject.rachel) // 'Rachel'
console.log(proxiedObject.emily) // 'No such friend'
const handler = {
get: function(target, key){
return Reflect.get(target, key) || 'No such friend';
}
};
const handler = {
get: function(target, key){
if(key.startsWith('_')){
throw new Error('Get out you filthy hippie!!');
}
return Reflect.get(target, key);
}
};
const c = {name: 'Chandler', _fear: 'Puppies'};
const chandler = new Proxy(c, handler);
console.log(chandler.name) // 'Chandler'
console.log(chandler._fear) // Error: Get out you filthy hippie!!
console.log(chandler._nickname) // Error: Get out you filthy hippie!!
const handler = {
get: function(target, key){
if(key.startsWith('_')){
throw new Error('Get out you filthy hippie!!');
}
return Reflect.get(target, key);
}
};
const handler = {
set: function(target, key, value) {
document.cookie = `${prop}=${value}`;
Reflect.set(target, key, value);
},
deleteProperty: function(target, key) {
document.cookie = `${key}=; expires=Thu, 01 Jan 1970 00:00:01 GMT;`;
return Reflect.deleteProperty(target, key);
}
}
const myCookies = new Proxy({}, handler);
myCookies.USER = 'Richard';
myCookies.VISITS = 99;
console.log(document.cookie); // USER=Richard; VISITS=99
const original = { ross, joey, chandler }
const handler = {
set: function(target, key, value){
if(key == 'ross' || key == 'joey' || key == 'chandler') {
throw 'You cant change one of the originals!'
} else {
Reflect.set(target, key, value);
}
}
}
const friends = new Proxy(original, handler);
friends.rachel = 'Rachel'; // ok
friends.joey = 'Drake Ramore'; // Error: You can't change...!
{
set: function(obj, prop, value) {
if (prop === 'name') {
if (typeof value !== 'string' || value === '') {
throw new Error('"name" should be a non-empty string');
}
} else if (prop === 'age') {
if (typeof value !== 'number' || value < 0 || value > 200) {
throw new Error('"age" should be a number between 0 and 200');
}
} else {
throw new Error('The only valid options are "name" and "age"');
}
Reflect.set(obj, prop, value);
}
}
friend.name = 'Joey';
friend.age = 30;
friend.sisters = 8;
// TypeError: The only valid options are
// "name" and "age"
friend.age = 'Why God Why';
// TypeError: "age" should be a number
// between 0 and 200
function Family() {
return new Proxy({}, handler);
}
const handler = {
get: function (target, key, receiver) {
if (!(key in target)) {
target[key] = Family(); // auto-create a sub-Tree
}
return Reflect.get(target, key, receiver);
}
};
const family = Family();
log(family) // {}
family.child1.child2.name = 'Emma';
log(family) // { child1: { child2: { name: 'Emma' }}}
family.child1.child3.name = 'Ben';
log(family) // { child1: { child2: { name: 'Emma' }}}
// { child3: { name: 'Ben' }}}
const parts = [];
const google = new Proxy(function(){}, {
get: function (object, prop) {
parts.push(prop);
return proxy;
},
apply: function() {
var returnValue = 'http://google.com/' + parts.join('/');
parts = [];
return returnValue;
}
});
google.search.products.mac.and.cheese()
// http://google.com/search/products/mac/and/cheese
google.search.ducks.or.clowns()
// http://google.com/search/ducks/or/clowns
const myArr = ['Joey', 'Chandler', 'Monica'];
const coolArray = new Proxy(myArr, {
get: function (array, ind) {
if(ind < 0) {
return Reflect.get(array, array.length + (1*ind));
} else {
return Reflect.get(array, ind);
}
}
});
coolArray[2]; // 'Monica'
coolArray[-1]; // 'Monica'
coolArray[3] = 'Ross'
coolArray[-1]; // 'Ross'
const original = { place: 'Central Perk' };
const handler = {
set: function(target, key, value) {
target._copy = target._copy || {...target};
Reflect.set(target._copy, key, value);
},
deleteProperty: function(target, key) {
target._copy = target._copy || {...target};
Reflect.deleteProperty(target._copy, key);
},
get: function(target, key){
if(key === 'commit') {
return () => new Proxy(target._copy, handler);
}
return Reflect.get(target, key);
}
}
let obj = new Proxy(original, handler);
obj.place = 'Times Square';
obj.place // 'Central Perk'
obj = obj.commit();
obj.place // 'Times Square'
delete obj[place];
obj.place // 'Times Square'
obj = obj.commit();
obj.place // undefined
original.place // 'Central Perk'
const original = { place: 'Central Perk' };
const handler = {
set: function(target, key, value) {
target._copy = target._copy || {...target};
Reflect.set(target._copy, key, value);
},
deleteProperty: function(target, key) {
target._copy = target._copy || {...target};
Reflect.deleteProperty(target._copy, key);
}
}
const original = { place: 'Central Perk' };
const handler = {
set: function(target, key, value) {
target._copy = target._copy || {...target};
Reflect.set(target._copy, key, value);
}
}
Can I use it???
ES
QUESTIONS?