AvraamMavridis
avraamakis
avraam.mavridis
Web Developer
(part 1)
-Doug Crockford
var Espresso = function( _coffee ) {
return {
coffee: _coffee
}
}
var Cappuccino = function( _coffee, _milk ){
return {
coffee: _coffee,
milk: _milk
}
}
console.log( Espresso.length ); // 1
console.log( Cappuccino.length ); // 2
A design pattern that allows behavior to be added to an individual object, either statically or dynamically.
var ExtraSugarDecoratorGenerator = function( Coffee ){
if( Coffee.length === 1 ){
return function( _coffee ){
var espresso = new Coffee( _coffee ) ;
var EspressoWithExtraSugar = Object.assign( espresso );
EspressoWithExtraSugar.sugar = 100;
return EspressoWithExtraSugar;
}
}
else if( Coffee.length === 2 ){
return function( _coffee, _milk ){
var cappuccino = new Coffee( _coffee, _milk ) ;
var CappuccinoWithExtraSugar = Object.assign( cappuccino );
CappuccinoWithExtraSugar.sugar = 80;
return CappuccinoWithExtraSugar;
}
}
}
import React from 'react';
import CSSModules from 'react-css-modules';
import styles from './table.css';
@CSSModules(styles)
export default class extends React.Component {
render () {
return <div styleName='table'>
<div styleName='row'>
<div styleName='cell'>A0</div>
<div styleName='cell'>B0</div>
</div>
</div>;
}
}
https://github.com/jayphelps/core-decorators.js
function Banner( a, b ) {
this.heights = [];
}
Object.defineProperty( Banner.prototype, 'length',
{ get: function() {
return this.heights.length;
}});
var x = new Banner();
x.heights.push( 120 );
x.heights.push( 240);
x.heights.push( undefined );
x.heights.push( "undefined" );
x.heights.push( Infinity );
console.log( x.length ) // 5
function foo( a, b, ...rest ) {
}
console.log( foo.length ); // 2
function foo( a, b, ...rest ) {
if( rest.length > 5 ){
console.log( 'Why so many values?' );
}
else{
console.log( 'Hello World' );
}
}
foo(1,2,3); // Hello World
foo(1,2,3,4); // Hello World
foo(1,2,3,4,5,6,7,8,9,10,11); // Why so many values?
The rest parameter syntax allows us to represent an indefinite number of arguments as an array.
var o = {};
var ö = Object.create({});
var õ = new Object();
Hm, not so empty...
console.log(o.constructor); //function Object() { [native code] }
console.log(ö.constructor); //function Object() { [native code] }
console.log(õ.constructor); //function Object() { [native code] }
var ø = Object.create(null);
console.log(ø.constructor); // undefined
class Cents
{
private:
int m_nCents;
public:
Cents(int nCents) { m_nCents = nCents; }
friend Cents operator+(const Cents &c1, const Cents &c2);
int GetCents() { return m_nCents; }
};
// note: this function is not a member function!
Cents operator+(const Cents &c1, const Cents &c2)
{
return Cents(c1.m_nCents + c2.m_nCents);
}
int main()
{
Cents cCents1(6);
Cents cCents2(8);
Cents cCentsSum = cCents1 + cCents2;
std::cout << "I have " << cCentsSum.GetCents() << " cents." << std::endl;
return 0;
}
@ToString
class Pizza {
String name
List<Topping> toppings
double price
}
@ToString
class Topping {
String name
double price
}
//Method with name "plus" will override the "+" operator.
Pizza plus(Topping topping) {
new Pizza(name: name, toppings: toppings + [topping], price: price + topping.price)
}
Pizza pizza = new Pizza(name: "Veg Extravaganza Pizza", price: 323.32, toppings: [])
Topping cheeseBurst = new Topping(name: "cheese Burst", price: 80)
Topping extraCheese = new Topping(name: "Extra Cheese", price: 40.43)
println (specialPizza)
/*
Pizza(Veg Extravaganza Pizza, [Topping(cheese Burst, 80.0), Topping(Extra Cheese, 40.43)], 514.4)
*/
class Book:
title = ''
pages = 0
def __init__(self, title='', pages=0):
self.title = title
self.pages = pages
def __add__(self, other):
return self.pages + other.pages
book1 = Book('Harry Potter', 700)
book2 = Book('Animal Farm', 250)
print (book1 + book2) # 950
function Book(title, pages){
this.pages = pages;
this.title = title;
}
Book.prototype.valueOf = function(){
return this.pages;
}
var a = new Book('Harry Potter', 700);
var b = new Book('Animal Farm', 250);
console.log( a + b ); // 950
var err = function( variable ){
throw new Error( `${variable} is mandatory` );
}
var foo = function( a = err('a'), b = err('b') ){
return a + b;
}
foo( undefined , 2 ) // Error, a is mandatory
foo( 10 ) // Error, b is mandatory
ES6
var find = function( arr, el ){
var i = arr.length;
while( i ){
if( arr[ i - 1] === el ){
return el;
}
i--;
}
return void('The element is not found');
}
var find = function( arr, el ){
var i = arr.length;
while( i ){
if( arr[ i - 1] === el ){
return el;
}
i--;
}
return;
}
// This throws an error
42.toFixed( 3 ); // SyntaxError
// But all these are valid js syntax ¯\(⊙︿⊙)/¯
(42).toFixed( 3 ); // "42.000"
42.0.toFixed( 3 ); // "42.000"
42..toFixed( 3 ); // "42.000"
42 .toFixed(3); // "42.000"
isNaN should check if
something === NaN
but...
isNaN( 5 ); // false
isNaN( NaN ) ; // true
isNaN('I am a string'); // true ???
Number.isNaN( 5 ); // false
Number.isNaN( NaN ); // true
Number.isNaN('I am a string'); // false
function isNaNSafe( a ){
return a !== a;
}
var b = NaN;
isNaNSafe(b); // true
isNaNSafe('something'); //false
isNaNSafe(5); //false
But how can we check that two values are equal if both are NaN ?
var a = NaN;
var b = NaN;
Object.is( a, b ) ; // true
if (!Object.is) {
Object.is = function(x, y) {
if (x === y) {
// +0 != -0
return x !== 0 || 1 / x === 1 / y;
} else {
// NaN == NaN
return x !== x && y !== y;
}
};
}
*Note: JS has -0 and +0
-0 === +0 //true
var a = new Array( 3 );
// older Firefox versions [,,,] or [,,]
// newer Chrome versions, Firefox [ undefined x 3 ]
var b = [ undefined, undefined, undefined ];
"0" in a; // false
"0" in b; // true
var a = new Array( 3 );
a.map(function(){ return 1; });
// We would expect [1,1,1] but... we get [ undefined x 3 ]
Hm...
map calls a provided callback function once for each element in an array, in order, and constructs a new array from the results. callback is invoked only for indexes of the array which have assigned values
var t = [];
t.length = 2;
t.map(function(){ return 1; }); // [undefined × 2]
// Hm, we cant...
var a = Array.apply(this, new Array(100));
/*[undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined]*/
a = a.map(function(){ return 1; });
/*[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]*/
// My fav
Array.apply( null, { length: 100 } );
Array.from(new Array(100));
Array.of(...(new Array(5)));
Array.apply(this, new Array(10)).map(function(){return 0; });
// [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Array.apply( this, new Uint16Array(10) );
// [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
(new Array(100)).fill(0);
[...Array(100)].map(() => 0);
Array.from(Array(100), () => 0)
Object.keys( Array.apply(null, Array(100))).map(() => 0);
Object.keys(new Int8Array(100)).map(()=> 0);
String()
Number()
Boolean()
Array()
Object()
Function()
RegExp()
Date()
Error()
Symbol()
var a = new Array(10);
var b = new Error('message');
var a = Array(10);
var b = Error('message');
===
var regx1 = /^a*b+/gi;
var regx2 = new RegExp('^a*b','gi');
Date() //"Mon Nov 23 2015 10:18:11 GMT+0100 (CET)"
var s = new Object('Hello');
var k = ' world'
console.log( s + k); // "something good"
var n = new Object(5);
var c = 10;
console.log( n + c ); // 15
try {
foo.bar();
} catch (e) {
if (e instanceof EvalError) {
alert(e.name + ': ' + e.message);
} else if (e instanceof RangeError) {
alert(e.name + ': ' + e.message);
}
// ... etc
}
function foo(a){
function boo(c){
this.$ = c;
}
boo.call(null, a );
}
foo(10);
console.log(window.$); // 10 ooooops!
function foo(a){
function boo(c){
this.$ = c;
}
// It is safer to pass an empty object
boo.call({}, a );
}
foo(10);
console.log(window.$); // jQuery, Alles gut
1. Mainly, you can receive a Promise value from another browser window (iframe, etc.), which would have its own Promise different from the one in the current window/frame, and that check would fail to identify the Promise instance.
2. Moreover, a library or framework may choose to vend its own Promises and not use the native Promise implementation to do so.
function isPromise(p){
return p !== null &&
( typeof p === "object" || typeof p === "function" ) &&
typeof p.then === "function";
}
...still, not enough
Object.prototype.then = function(){};
Array.prototype.then = function(){};
var v1 = { hello: "world" };
var v2 = [ "Hello", "World" ];
Both v1 and v2 will be assumed to be thenables. You can't control or predict if any other code accidentally or maliciously adds then(..) to any of the native prototypes.
try {
foo();
}
catch (err) {
// handle error
}
The try..catch here works only from the perspective that the foo() call will either succeed or fail immediately, synchronously. If foo() was itself its own async completing function, any async errors inside it would not be catchable.
If you use the Promise API in an invalid way and an error occurs that prevents proper Promise construction, the result will be an immediately thrown exception, not a rejected Promise. Some examples of incorrect usage that fail Promise construction:
new Promise(null);
Promise.all();
Promise.race(42);
var p = Promise.resolve( 42 );
p.then(
function fulfilled(msg){
foo(msg); // throw error, foo undefined
}
)
.catch( handleErrors );
What happens if handleErrors(..) itself also has an error in it? Who catches that?
You can't just stick another catch(..)
Promise.race()
Promise.all()
Promise.none() //not part of the standard
Promise.some() //not part of the standard
Promise.any() //not part of the standard
Notes:
A "race" requires at least one "runner," so if you pass an empty array, Promise will never resolve.
You are requesting data from various APIs. If one fails you want to be able to present data to the users from the other APIs. How can you do that in an effective way without using nested promises if the only thing that you have is Promise.all?
Promise.settle( arrayOfPromises ).then(function(results){
for(var i = 0; i < results.length; i++){
if(results[i].isFulfilled()){
// results[i].value to get the value
}
}
});
function settle(promises) {
return Promise.resolve()
.then(function () {
return promises;
})
.then(function (promises) {
if (!Array.isArray(promises)) throw new TypeError('Expected an array of Promises');
var promiseResults = promises.map(function (promise) {
return Promise.resolve()
.then(function () {
return promise;
})
.then(function (result) {
return promiseResult(result);
})
.catch(function (err) {
return promiseResult(null, err);
});
});
return Promise.all(promiseResults);
});
}
function promiseResult(result, err) {
var isFulfilled = (typeof err === 'undefined');
var value = isFulfilled
? returns.bind(result)
: throws.bind(new Error('Promise is rejected'));
var isRejected = !isFulfilled;
var reason = isRejected
? returns.bind(err)
: throws.bind(new Error('Promise is fulfilled'));
return {
isFulfilled: returns.bind(isFulfilled),
isRejected: returns.bind(isRejected),
value: value,
reason: reason
};
}
function returns() {
return this;
}
function throws() {
throw this;
}
(function(){
console.log('>>>');
})();
(function(){
console.log('>>>');
}());
(function(){
console.log('>>>');
}).call(null);
!function(){console.log('>>>')}();
+function(){console.log('>>>')}();
-function(){console.log('>>>')}();
~function(){console.log('>>>')}();
true&function(){console.log('>>>')}();
true,function(){console.log('>>>')}();
true||function(){console.log('>>>')}();
true^function(){console.log('>>>')}();
new function(){console.log('>>>')}();
//My fav
void function(){console.log('>>>')}();
var a = new Boolean( false );
var b = new Number( 0 );
var c = new String( "" );
Someone could think that we are referring to objects wrapped around obviously falsy values
But obviously...
Boolean(a); // true
!!b // true
a & b & c // true
There are certain cases where browsers have created their own sort of exotic values behavior, namely this idea of "falsy objects," on top of regular JS semantics.
document.all // HTMLAllCollection[582]
Boolean(document.all) // false
var foo = function(){
return {};
}
var c = new foo;
var d = foo();
var e = new foo();
console.log(c); //{}
console.log(d); //{}
console.log(e); //{}
var cryptoStor = new Uint16Array(8);
window.crypto.getRandomValues(cryptoStor);
// [22237, 22562, 59970, 4209, 47246, 63294, 21811, 6254]
To guarantee enough performance, implementations are not using a truly random number generator, but they are using a pseudo-random number generator seeded with a value with enough entropy.
More: https://medium.com/@betable/tifu-by-using-math-random-f1c308c4fd9d#.yoelzmgpo
1. How can we make this happen?
new Number(2) == 3; // true
2. Write a function that will output "Hello World":
-Without assigning any variable directly equal to a string,number,null, undefined,boolean or any operation between them
-Without using Regex, typeof, instanceof
-Without declaring any function with the name "hello world" or similar
-Without declaring any array or any object
(Contact me for the solutions)
AvraamMavridis
avraamakis
avraam.mavridis