├── .gitignore
├── ES6.png
├── LICENSE
├── README.md
├── session-1
├── .babelrc
├── README.md
├── dist
│ └── bundle.js
├── index.html
├── package.json
├── src
│ ├── 00_scope.js
│ ├── 01_context.js
│ ├── 02_scope.js
│ ├── 03_const.js
│ └── index.js
└── webpack.config.js
├── session-2
├── .babelrc
├── 00_template_string.js
├── 01_multiple_lines.js
├── 02_tagging.js
├── 03_raw.js
├── 03_tagging.js
├── 04_i18n.js
├── 05_destrucuring_arrays.js
├── 06_destructuring_objects.js
├── 07_default_values.js
├── 08_spread.js
├── 09_arrow.js
├── 10_arrow_this.js
├── README.md
├── dev.webpack.config.js
├── package.json
└── src
│ └── index.js
├── session-3
├── .babelrc
├── 00_constructor.js
├── 00_context.js
├── 00_prototype.js
├── 01_es5_classes.js
├── 02_es5_subclasses.js
├── 03_es5_clone.js
├── 04_es6_classes.js
├── 05_es6_subclasses.js
├── 06_object_literals.js
├── 07_iterators.js
├── 08_generators.js
├── README.md
└── package.json
├── session-4
├── .babelrc
├── 00_string_methods.js
├── 01_Number_Math.js
├── 02_array.js
├── 03_sets.js
├── 04_maps.js
├── 05_weak_sets.js
├── 06_weak_maps.js
├── 07_animation_es5.js
├── 08_animation_promise.js
├── 09_animation_parallel.js
├── 10_promise.js
├── README.md
├── modules
│ ├── aliases.js
│ ├── app.js
│ ├── mathematics.js
│ ├── persona.js
│ ├── suma.js
│ └── vars.js
└── package.json
├── session-5
├── .babelrc
├── 00_symbols.js
├── 01_proxies.js
├── 02_reflection.js
├── 03_decorators.js
├── README.md
└── package.json
└── session-6
├── .babelrc
├── README.md
├── dist
├── main.css
└── main.js
├── package.json
├── src
├── components
│ ├── card
│ │ ├── _index.scss
│ │ └── index.js
│ └── html
│ │ ├── div.js
│ │ ├── htmlComponent.js
│ │ ├── image.js
│ │ ├── index.js
│ │ └── text.js
├── domain
│ ├── entity.js
│ ├── factories
│ │ └── pokemon.js
│ ├── index.js
│ ├── pokemon
│ │ ├── apiPokemonRepository.js
│ │ ├── pokemonEntity.js
│ │ ├── pokemonListUseCase.js
│ │ ├── pokemonRepository.js
│ │ └── spriteEntity.js
│ └── useCase.js
├── index.js
└── index.scss
└── webpack.config.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 |
11 | # Directory for instrumented libs generated by jscoverage/JSCover
12 | lib-cov
13 |
14 | # Coverage directory used by tools like istanbul
15 | coverage
16 |
17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
18 | .grunt
19 |
20 | # node-waf configuration
21 | .lock-wscript
22 |
23 | # Compiled binary addons (http://nodejs.org/api/addons.html)
24 | build/Release
25 |
26 | # Dependency directory
27 | node_modules
28 |
29 | # Optional npm cache directory
30 | .npm
31 |
32 | # Optional REPL history
33 | .node_repl_history
34 |
--------------------------------------------------------------------------------
/ES6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EscuelaIt/Curso-ECMAScript-6/2ae84040cf35d01c45dd74b44e966a43277484fe/ES6.png
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Curso Javascript ECMAScript 6
2 | Repositorio del [Curso ECMAScript 6](http://escuela.it/cursos/javascript-ecmascript-6/)
3 |
4 | ## Slides
5 | [Aprende ECMAScript 2015](https://slides.com/danieldelacruzcalvo/aprende-ecmascript-2015)
6 |
7 | ## Recursos de aprendizaje
8 | * [ES6: New Features & Comparison](http://es6-features.org/)
9 | * [ECMAScript 2015 (ES6) in Node.JS](https://nodejs.org/en/docs/es6/)
10 | * [Learn ES2015 with Babel](https://babeljs.io/docs/learn-es2015/)
11 | * [Tabla de compatibilidad de ECMAScript 2015](https://kangax.github.io/compat-table/es6/)
12 | * [Lista de Recursos para aprender ECMAScript 2015](https://github.com/ericdouglas/ES6-Learning)
13 |
14 | 
15 |
--------------------------------------------------------------------------------
/session-1/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | presets: [ 'es2015' ],
3 | plugins: []
4 | }
--------------------------------------------------------------------------------
/session-1/README.md:
--------------------------------------------------------------------------------
1 | # Sesión 1
2 |
3 | ### Enlaces
4 |
5 | * [Babel](https://babeljs.io)
6 | * [ECMAScript 2015 (ES6) in Node.js](https://nodejs.org/en/docs/es6/)
7 | * [Immutable.js](https://facebook.github.io/immutable-js/)
8 | * [Material Theme](https://equinusocio.github.io/material-theme/)
9 |
10 | ### Recursos
11 | Para que podamos utilizar los packages instalados en un proyecto sin tener que definir la ruta `./node_modules/.bin/` en cada uno de ellos, podemos insertar en nuestro fichero `.bashrc`, `.bash_profile`, etc... la siguiente línea para añadir al `PATH` la ruta de los binarios.
12 |
13 | ```
14 | export PATH=$PATH:./node_modules/.bin
15 | ```
16 |
17 |
--------------------------------------------------------------------------------
/session-1/dist/bundle.js:
--------------------------------------------------------------------------------
1 | /******/ (function(modules) { // webpackBootstrap
2 | /******/ // The module cache
3 | /******/ var installedModules = {};
4 |
5 | /******/ // The require function
6 | /******/ function __webpack_require__(moduleId) {
7 |
8 | /******/ // Check if module is in cache
9 | /******/ if(installedModules[moduleId])
10 | /******/ return installedModules[moduleId].exports;
11 |
12 | /******/ // Create a new module (and put it into the cache)
13 | /******/ var module = installedModules[moduleId] = {
14 | /******/ exports: {},
15 | /******/ id: moduleId,
16 | /******/ loaded: false
17 | /******/ };
18 |
19 | /******/ // Execute the module function
20 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
21 |
22 | /******/ // Flag the module as loaded
23 | /******/ module.loaded = true;
24 |
25 | /******/ // Return the exports of the module
26 | /******/ return module.exports;
27 | /******/ }
28 |
29 |
30 | /******/ // expose the modules object (__webpack_modules__)
31 | /******/ __webpack_require__.m = modules;
32 |
33 | /******/ // expose the module cache
34 | /******/ __webpack_require__.c = installedModules;
35 |
36 | /******/ // __webpack_public_path__
37 | /******/ __webpack_require__.p = "";
38 |
39 | /******/ // Load entry module and return exports
40 | /******/ return __webpack_require__(0);
41 | /******/ })
42 | /************************************************************************/
43 | /******/ ([
44 | /* 0 */
45 | /***/ function(module, exports) {
46 |
47 | "use strict";
48 |
49 | var suma = function suma(a, b) {
50 | return a + b;
51 | };
52 | debugger;
53 | console.log(suma(2, 3));
54 |
55 | /***/ }
56 | /******/ ]);
--------------------------------------------------------------------------------
/session-1/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Document
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/session-1/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "session-1",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "babel": "babel src --out-dir dist",
8 | "dist": "webpack",
9 | "start": "babel-node"
10 | },
11 | "keywords": [],
12 | "author": "",
13 | "license": "ISC",
14 | "devDependencies": {
15 | "babel-cli": "^6.5.1",
16 | "babel-loader": "^6.2.3",
17 | "babel-preset-es2015": "^6.5.0",
18 | "webpack": "^1.12.14"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/session-1/src/00_scope.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | var x;
3 | console.log(x);
4 | if(true){
5 | x = 'hola mundo';
6 | }
7 | console.log(x);
8 | })();
9 |
10 |
--------------------------------------------------------------------------------
/session-1/src/01_context.js:
--------------------------------------------------------------------------------
1 | // var obj = {
2 | // foo: function() {
3 | // console.log(this === obj);
4 | // }
5 | // };
6 |
7 | // obj.foo();
8 |
9 | function bar(){
10 | console.log(this);
11 | }
12 |
13 | new bar();
--------------------------------------------------------------------------------
/session-1/src/02_scope.js:
--------------------------------------------------------------------------------
1 | var a = 'I am global';
2 |
3 | function foo(){
4 | let b = 'I am local';
5 | console.log('Existe a en el alcance local?', !!a);
6 | console.log('Existe b en el alcance local?', !!b);
7 |
8 | if(true){
9 | let c = 'Soy una variable de la condición if';
10 | }
11 |
12 | let c = 3;
13 |
14 | console.log('cuanto vale c?', c);
15 |
16 | // console.log('Existe c fuera del if?', !!c);
17 |
18 | for(let d = 0; d < 10; d++){
19 | // ...
20 | }
21 |
22 | // console.log('Existe d fuera del for?', !!d);
23 | }
24 |
25 | foo();
26 | // console.log('Existe a en el alcance global?', !!a);
27 | // console.log('Existe b en el alcance global?', !!b);
--------------------------------------------------------------------------------
/session-1/src/03_const.js:
--------------------------------------------------------------------------------
1 | const USER = {
2 | name: 'Daniel',
3 | surname: 'de la Cruz',
4 | age: 32
5 | };
6 |
7 | USER.name = 'Joan';
8 | USER.age = 'cuarenta';
9 | USER.kk = 3;
10 |
11 | delete USER.age;
12 |
13 | console.log(USER);
14 | const LIGHT = '#AAA';
15 |
16 | const colors: {
17 | background: LIGHT
18 | }
--------------------------------------------------------------------------------
/session-1/src/index.js:
--------------------------------------------------------------------------------
1 | const suma = (a, b) => a + b;
2 | debugger;
3 | console.log(suma(2, 3));
--------------------------------------------------------------------------------
/session-1/webpack.config.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 | var webpack = require('webpack');
3 |
4 | const config = {
5 | entry: path.join(__dirname, '/src'),
6 | output: {
7 | path: './dist',
8 | filename: 'bundle.js'
9 | },
10 | module: {
11 | loaders: [{
12 | test: /\.js?$/,
13 | loaders: [ 'babel' ],
14 | exclude: /node_modules/
15 | }]
16 | },
17 | new webpack.optimize.UglifyJsPlugin({
18 | compress: {
19 | warnings: false
20 | }
21 | })
22 | }
23 |
24 | module.exports = config;
--------------------------------------------------------------------------------
/session-2/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [ "es2015" ],
3 | "plugins": []
4 | }
--------------------------------------------------------------------------------
/session-2/00_template_string.js:
--------------------------------------------------------------------------------
1 | const hello = 'Hello';
2 | const world = "World";
3 |
4 | const helloWorld = `${hello}, ${world}!`;
5 |
6 | console.log(helloWorld);
7 |
--------------------------------------------------------------------------------
/session-2/01_multiple_lines.js:
--------------------------------------------------------------------------------
1 | const lorem = `Lorem ipsum dolor sit amet,
2 | consectetur adipisicing elit,
3 | sed do eiusmod tempor incididunt
4 | ut labore et dolore magna aliqua.
5 | Ut enim ad minim veniam,
6 | quis nostrud exercitation ullamco
7 | laboris nisi ut aliquip ex ea commodo consequat.
8 | Duis aute irure dolor in reprehenderit in
9 | voluptate velit esse cillum dolore eu fugiat
10 | nulla pariatur. Excepteur sint occaecat cupidatat
11 | non proident, sunt in culpa qui officia deserunt
12 | mollit anim id est laborum. `;
13 |
14 | console.log(lorem);
15 |
--------------------------------------------------------------------------------
/session-2/02_tagging.js:
--------------------------------------------------------------------------------
1 | // Sin spread operator
2 | function tag(strings, arg1, arg2){
3 | console.log(strings)
4 | console.log(arg1)
5 | console.log(arg2)
6 | console.log(arguments)
7 | }
8 |
9 | const pepito = 'Pepito';
10 | const jose = 'Jose';
11 |
12 | console.log(tag`Hola, don ${pepito}, hola don ${jose}`);
13 |
14 | // Con spread operator
15 | function newTag(strings, ...args) {
16 | console.log(strings)
17 | console.log(args)
18 | }
19 |
20 | console.log(newTag`Hola, don ${pepito}, hola don ${jose}`);
--------------------------------------------------------------------------------
/session-2/03_raw.js:
--------------------------------------------------------------------------------
1 | const raw = function(strings, args) {
2 | return strings.raw[0];
3 | }
4 | console.log(raw`Hello!\n`);
5 | console.log('next line');
6 | console.log(`Hello!\n`);
7 | console.log('next line');
--------------------------------------------------------------------------------
/session-2/03_tagging.js:
--------------------------------------------------------------------------------
1 | const tag = function(strings, args) {
2 | return strings.map(function(s){
3 | return s.split('').map(function(s){
4 | return `${s}.`;
5 | })
6 | .join('')
7 | })
8 | .join('');
9 | }
10 |
11 | console.log(tag`Hello, World!`);
--------------------------------------------------------------------------------
/session-2/04_i18n.js:
--------------------------------------------------------------------------------
1 | const dictionary = {
2 | es: {
3 | 'days ago': 'hace %{count} días'
4 | },
5 | en: {
6 | 'days ago': '%{count} days ago'
7 | }
8 | };
9 |
10 | const i18n = function(strings, args) {
11 | const key = strings.join('').trim();
12 | return dictionary[culture][key].replace('%{count}', args);
13 | };
14 |
15 | let culture = 'es';
16 | console.log(i18n`${8} days ago`);
17 |
18 | culture = 'en';
19 | console.log(i18n`${8} days ago`);
20 |
--------------------------------------------------------------------------------
/session-2/05_destrucuring_arrays.js:
--------------------------------------------------------------------------------
1 | const numbers = ['1', '2', '3'];
2 |
3 | // without destructuring
4 | const one = numbers[0];
5 | const two = numbers[1];
6 | const three = numbers[2];
7 |
8 | // with destructuring
9 | const [uno, dos, tres] = numbers;
10 |
11 | console.log(one, two, three);
12 | console.log(uno, dos, tres);
13 |
14 | // also, without assignment:
15 | let ichi, ni, san;
16 | [ichi, ni, san] = ['uno', 'dos', 'tres'];
17 |
18 | console.log(ichi, ni, san);
19 |
20 | // destructuring assignment returning values from a function
21 | function users(){
22 | return ['joan', 'carlos', 'david', 'dani'];
23 | }
24 |
25 | let [joan, carlos, david, dani] = users();
26 | console.log(joan, carlos, david, dani);
27 |
--------------------------------------------------------------------------------
/session-2/06_destructuring_objects.js:
--------------------------------------------------------------------------------
1 | // object destructuring works exactly the same way as in arrays
2 | let object = { one: 1, two: 2 };
3 | let {one, two} = object;
4 | console.log(one, two); // 1 2
5 |
6 | // We can destructure values when passing arguments to a function
7 | function suma({a, b} = {}) {
8 | return a + b;
9 | };
10 |
11 | // now, we can pass separate values
12 | const three = 3;
13 | const four = 4;
14 | console.log(suma({a: three, b: four}));
15 |
16 | // If the properties have the same name than the declared in the function definition, ES6 assigns them automatically
17 | const a = 3;
18 | const b = 4;
19 | console.log(suma({a, b}));
20 |
21 | // or, an object to get its properties destructured
22 | const numbers = {
23 | a: 5,
24 | b: 6
25 | };
26 | console.log(suma(numbers));
27 |
28 | // we can alias our destructured variables:
29 | const persona = { nombre: 'Daniel', apellidos: 'de la Cruz' };
30 | const { nombre: name, apellidos: surname } = persona;
31 | console.log(name);
32 | console.log(surname);
33 |
--------------------------------------------------------------------------------
/session-2/07_default_values.js:
--------------------------------------------------------------------------------
1 | // ES5
2 | function drawCircle(options){
3 | options = options === undefined ? {} : options;
4 | var radius = options.radius === undefined ? 30 : options.radius;
5 | var coords = options.coords === undefined ? { x: 0, y: 0 } : options.coords;
6 |
7 | console.log(radius, coords);
8 | // finally, draw the circle
9 | }
10 |
11 | // ES6
12 | function drawCircle({radius = 30, coords = { x: 0, y: 0}} = {}) {
13 | console.log(radius, coords);
14 | // draw the circle
15 | };
16 |
17 | drawCircle(); // radius: 30, coords.x: 0, coords.y: 0 }
18 | drawCircle({radius: 10}); // radius: 10, coords.x: 0, coords.y: 0 }
19 | drawCircle({coords: {y: 10, x: 30}, radius: 10}); // radius: 10, coords.x: 30, coords.y: 10 }
20 |
21 | function sayHello({
22 | name = 'Joan',
23 | surname = 'Leon'
24 | } = {}) {
25 | console.log('Hello', name, surname);
26 | };
27 |
28 | sayHello();
--------------------------------------------------------------------------------
/session-2/08_spread.js:
--------------------------------------------------------------------------------
1 | // El operador de propagación spread operator permite que una
2 | // expresión sea expandida en situaciones donde se esperan múltiples
3 | // argumentos (llamadas a funciones) o múltiples elementos
4 | // (arrays).
5 |
6 | const values = [1, 2, 3, 4];
7 |
8 | console.log(values); // returns an array
9 | console.log(...values); // spreads the array and returns the values
10 |
11 | // We can define a spread parameter
12 | function f(args) {
13 | return args.length;
14 | }
15 |
16 | console.log('Without spreading', f(1, 2, 3));
17 |
18 | function fspread(...args) {
19 | return args.length;
20 | }
21 |
22 | console.log('With spreading', fspread(1, 2, 3));
23 |
24 | // We can also spread on passing the arguments
25 | function suma(x, y, z) {
26 | return x + y + z;
27 | }
28 |
29 | console.log(suma(...[1, 2, 3])); // 6
30 |
31 | // Spread object properties
32 | const worker = {
33 | id: 1337,
34 | name: 'John',
35 | surname: 'Woo',
36 | age: 35,
37 | job: 'UI designer'
38 | };
39 |
40 | const customize = function(worker){
41 | return {
42 | ...worker,
43 | fullName: `Mr./Mrs. ${worker.surname}, ${worker.name}`,
44 | age: `${worker.age} years old`
45 | };
46 | };
47 |
48 | console.log(customize(worker));
49 |
--------------------------------------------------------------------------------
/session-2/09_arrow.js:
--------------------------------------------------------------------------------
1 | const echo = text => text;
2 | console.log(echo('Hello, arrow functions!'));
3 |
4 | // with arguments
5 | const suma = (a, b, c) => a + b + c;
6 | console.log(suma(1, 2, 3));
7 |
8 | // or without
9 | const greet = () => 'Hi again!';
10 | console.log(greet());
11 |
12 | // other es6 function improvements are also valid here
13 | const concat = (...args) => args.join(', ');
14 | console.log(concat('one', 'two', 'three', 'four'));
15 |
16 | // For complex operations, we can give the arrow function a body
17 | const resize = ({x, y}, ratio) => {
18 | return {
19 | x: x * ratio,
20 | y: y * ratio
21 | };
22 | };
23 |
24 | console.log(resize({x: 5, y: 15}, 100));
25 |
--------------------------------------------------------------------------------
/session-2/10_arrow_this.js:
--------------------------------------------------------------------------------
1 | const randomWinner = function(drivers) {
2 | const winner = Math.floor(Math.random() * (0 - drivers.length) + drivers.length);
3 | return drivers[winner];
4 | };
5 |
6 | const F1Race = {
7 | drivers: [
8 | 'Alonso',
9 | 'Vettel',
10 | 'Button',
11 | 'Massa'
12 | ],
13 |
14 | init: function() {
15 | console.log('Los siguientes pilotos van a comenzar la carrera:', this.drivers);
16 | setTimeout((function() {
17 | console.log('El ganador es', randomWinner(this.drivers));
18 | }), 1000);
19 | // }).bind(this), 1000);
20 | }
21 | };
22 |
23 | F1Race.init();
24 |
25 | //// If we redefine the init function including an arrow:
26 |
27 | // F1Race.init = function() {
28 | // console.log('Los siguientes pilotos van a comenzar la carrera:', this.drivers);
29 | // setTimeout(() => console.log('El ganador es', randomWinner(this.drivers)), 1000);
30 | // };
31 | //
32 | // F1Race.init();
33 |
--------------------------------------------------------------------------------
/session-2/README.md:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/session-2/dev.webpack.config.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 | var webpack = require('webpack');
3 |
4 | var APP_PATH = path.join(__dirname, '/src');
5 |
6 | module.exports = {
7 | context: APP_PATH,
8 | entry: './index.js',
9 | output: {
10 | path: path.join(__dirname, 'dist'),
11 | filename: '[name].js',
12 | publicPath: 'http://localhost:3000/dist'
13 | },
14 | devServer: {
15 | port: 3000,
16 | stats: { colors: true },
17 | inline: true,
18 | publicPath: '/dist/'
19 | },
20 | devtool: 'source-map',
21 | module: {
22 | loaders: [{
23 | test: /\.js$/,
24 | loaders: [ 'babel' ],
25 | exclude: /node_modules/
26 | }]
27 | },
28 | plugins: [
29 | new webpack.HotModuleReplacementPlugin()
30 | ]
31 | };
--------------------------------------------------------------------------------
/session-2/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "session-2",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "babel-node",
8 | "dev": "webpack-dev-server --config dev.webpack.config.js"
9 | },
10 | "keywords": [],
11 | "author": "",
12 | "license": "ISC",
13 | "devDependencies": {
14 | "babel-cli": "^6.5.1",
15 | "babel-loader": "^6.2.3",
16 | "babel-preset-es2015": "^6.5.0",
17 | "webpack": "^1.12.14",
18 | "webpack-dev-server": "^1.14.1"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/session-2/src/index.js:
--------------------------------------------------------------------------------
1 | const h1 = function(text) {
2 | const h1 = document.createElement('h1');
3 | h1.appendChild(document.createTextNode(text));
4 | return h1;
5 | };
6 |
7 | document.body.appendChild(h1('Hola alumnos de Escuela IT'));
--------------------------------------------------------------------------------
/session-3/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [ "es2015", "stage-2" ],
3 | "plugins": []
4 | }
--------------------------------------------------------------------------------
/session-3/00_constructor.js:
--------------------------------------------------------------------------------
1 | // cualquier función utilizada como un constructor se convierte en un constructor :)
2 | var Vehicle = function Vehicle() {
3 | console.log('Sólo soy una función!');
4 | }
5 |
6 | var motorcycle = new Vehicle();
7 |
8 | console.log(typeof Vehicle); // function
9 | console.log(typeof Vehicle()); // undefined
10 | console.log(typeof new Vehicle()); // object
11 |
12 | // NOTA: No es aconsejable retornar ningún valor en funciones constructoras,
13 | // ya que el valor retornado sobreescribirá la instancia del objeto creado
14 |
15 | // motorcycle tiene una propiedad constructor que es la función Vehicle
16 | console.log(motorcycle.constructor === Vehicle);
17 |
18 | // motorcycle es UNA INSTANCIA de Vehicle
19 | console.log(motorcycle instanceof Vehicle);
20 |
21 | // la propiedad constructor no aparece si enumeramos las propiedades de motorcycle
22 | console.log(motorcycle);
23 |
24 | // Pero podemos crearla y sobreescribirla
25 | var Postman = function Postman() {};
26 | motorcycle.constructor = Postman;
27 |
28 | console.log(motorcycle);
29 |
30 | // Pero, sigue siendo una instancia de Vehicle?
31 | console.log(motorcycle.constructor === Postman);
32 | console.log(motorcycle instanceof Postman);
33 | console.log(motorcycle instanceof Vehicle);
--------------------------------------------------------------------------------
/session-3/00_context.js:
--------------------------------------------------------------------------------
1 | var Person = function Person(name) {
2 | this.name = name;
3 | }
4 |
5 | var myself = new Person('Dani');
6 |
7 | // name solo existe dentro del contexto del objeto 'myself'
8 | console.log(typeof name); // undefined
9 | console.log(myself.name); // Dani
10 |
11 | // Si utilizamos Person como una función no constructora:
12 | Person('Joan');
13 | console.log(name);
--------------------------------------------------------------------------------
/session-3/00_prototype.js:
--------------------------------------------------------------------------------
1 | var Vehicle = function Vehicle() {
2 | console.log('Sólo soy una función!');
3 | }
4 |
5 | Vehicle.prototype.wheelCount = 4;
6 |
7 | var truck = new Vehicle();
8 | console.log(truck.wheelCount); // 4
9 |
10 | //
11 | Vehicle.prototype.wheelCount = 6;
12 | console.log(truck.wheelCount);
13 |
14 | // modificar wheelCount en la instancia no modifica
15 | // el prototype de la función constructora
16 | truck.wheelCount = 8;
17 | console.log(Vehicle.prototype.wheelCount);
18 | console.log(truck.wheelCount);
19 |
20 | // wheelCount ya no está delegado
21 | Vehicle.prototype.wheelCount = 10;
22 | console.log(truck.wheelCount);
23 |
24 | // obviamente siempre podemos hacer lo mismo con métodos, ya que
25 | // un método no es más que una función asignada a una propiedad:
26 | Vehicle.prototype.go = function go() { return 'Brooommmm!' };
27 | console.log(truck.go());
--------------------------------------------------------------------------------
/session-3/01_es5_classes.js:
--------------------------------------------------------------------------------
1 | var Vehicle = function Vehicle(color, model) {
2 | // Initialization
3 | this.color = color;
4 | this.model = model;
5 | }
6 |
7 | // Instance methods
8 | Vehicle.prototype = {
9 | go: function go() {
10 | return "Brrooooom!";
11 | },
12 | whoami: function whoami() {
13 | return "I am a " + this.color + " " + this.model;
14 | }
15 | }
16 |
17 | var motorcycle = new Vehicle('yellow', 'Vespa');
18 |
19 | console.log(motorcycle.whoami());
20 | console.log(motorcycle.go());
21 |
--------------------------------------------------------------------------------
/session-3/02_es5_subclasses.js:
--------------------------------------------------------------------------------
1 | var Vehicle = function Vehicle(color, model) {
2 | // Initialization
3 | this.color = color;
4 | this.model = model;
5 | }
6 |
7 | // Instance methods
8 | Vehicle.prototype = {
9 | go: function go() {
10 | return "Brrooooom!";
11 | },
12 | whoami: function whoami() {
13 | return "I am a " + this.color + " " + this.model;
14 | }
15 | }
16 |
17 | var Car = function Car() {};
18 | Car.prototype = new Vehicle('red', 'Ford');
19 | Car.prototype.honk = function honk() { return "MOOOOC!" };
20 | var car = new Car();
21 | console.log(car.honk()); // MOOOOC!
22 | console.log(car.go()); // Brrooooom!
23 | console.log(car.color); // red
24 | console.log(car instanceof Car); // true
25 | console.log(car instanceof Vehicle); // true
--------------------------------------------------------------------------------
/session-3/03_es5_clone.js:
--------------------------------------------------------------------------------
1 | function clone(parent){
2 | var Clone = function() {};
3 | Clone.prototype = parent;
4 | return new Clone();
5 | }
6 |
7 | var car = { color: 'white' };
8 | var ibiza = clone(car);
9 | var leon = clone(car);
10 | var toledo = clone(car);
11 | toledo.color = 'blue';
12 |
13 | console.log(ibiza.color); // white
14 | console.log(leon.color); // white
15 | console.log(toledo.color); // blue
16 |
17 | car.color = 'black';
18 |
19 | console.log(ibiza.color); // black
20 | console.log(leon.color); // black
21 | console.log(toledo.color); // blue
--------------------------------------------------------------------------------
/session-3/04_es6_classes.js:
--------------------------------------------------------------------------------
1 | class Point {
2 | constructor(x, y) {
3 | this.x = x;
4 | this.y = y;
5 | }
6 | toString() {
7 | return `(${this.x}, ${this.y})`;
8 | }
9 | }
10 |
11 | var p = new Point(25, 8);
12 | console.log(p.toString()); //(25, 8)
13 |
14 |
15 | // la clase no es más que una función!!
16 | console.log(typeof Point); // function
17 |
18 | // pero no puede ser utilizada directamente, solo con new
19 | // Point();
20 | // > TypeError: Classes can't be function-called
21 |
22 | class Sample{
23 | constructor(value){
24 | this.value = value;
25 | }
26 | static staticMethod(){
27 | return 'Puedes llamar al método estático sin instanciar la clase';
28 | }
29 | prototypeMethod(){
30 | return 'Solo puedes llamar al método de prototipo mediante una instancia de la clase';
31 | }
32 | }
33 |
34 | const sample = new Sample(123);
35 | console.log(sample);
36 | console.log(Sample.staticMethod());
37 | //console.log(Sample.prototypeMethod()); // TypeError: Sample.prototipo is not a function
38 | console.log(sample.prototypeMethod());
39 | //console.log(sample.staticMethod()); // TypeError: sample.staticMethod is not a function
--------------------------------------------------------------------------------
/session-3/05_es6_subclasses.js:
--------------------------------------------------------------------------------
1 | class Point {
2 | constructor(x, y) {
3 | this.x = x;
4 | this.y = y;
5 | }
6 | toString() {
7 | return `(${this.x}, ${this.y})`;
8 | }
9 | }
10 |
11 | // La clase padre asigna las coordenadas mediante super()
12 | // La subclase sobreescribe el toString()
13 | class ColorPoint extends Point {
14 | constructor(x, y, color) {
15 | super(x, y);
16 | this.color = color;
17 | }
18 | toString() {
19 | return `Punto dibujado en coordenadas ${super.toString()} de color ${this.color}`;
20 | }
21 | }
22 |
23 | const cp = new ColorPoint(25, 8, 'verde');
24 | console.log(cp.toString()); // (25, 8) de color verde
25 | console.log(cp instanceof ColorPoint) // true
26 | console.log(cp instanceof Point) // true
--------------------------------------------------------------------------------
/session-3/06_object_literals.js:
--------------------------------------------------------------------------------
1 | // un object literal es una lista de pares de clave-valor
2 | // rodeados por corchetes
3 | var myObject = {
4 | name: 'Daniel',
5 | age: 32,
6 | married: true
7 | }
8 |
9 | // pueden ser de cualquier tipo
10 | var mySuperCoolObject = {
11 | images: ["one.gif", "two.gif", "three.gif", "four.gif"],
12 | location: {
13 | x: 40.8374,
14 | y: 300.1771
15 | },
16 | move: function(x, y) {
17 | this.location.x += x;
18 | this.location.y += y;
19 | }
20 | };
21 |
22 | const myES6Object = {
23 | foo(){
24 | // ...
25 | },
26 | bar(x, y){
27 | // ...
28 | }
29 | }
30 |
31 | const propertyKey = 'foo';
32 | const ar = 'ar';
33 | const object = {
34 | [propertyKey]: true,
35 | [`b${ar}`]: 123
36 | };
37 |
38 | console.log(object)
39 |
40 | const methodKey = 'greeting';
41 | const yetAnotherObject = {
42 | [methodKey]() {
43 | return 'Hello!';
44 | }
45 | };
46 |
47 | console.log(yetAnotherObject.greeting())
--------------------------------------------------------------------------------
/session-3/07_iterators.js:
--------------------------------------------------------------------------------
1 | // for of crea un bucle que itera sobre objetos iterables.
2 |
3 | var numbers = [1, 2, 3, 4];
4 |
5 | for(const number of numbers){
6 | console.log(number);
7 | }
8 |
9 | // Creamos objeto iterable con una función next();
10 | // Llamar a .next() nos dará un objeto coneniendo el valor,
11 | // o indicándonos que no hay más valores
12 | const numberIterator = numbers[Symbol.iterator]();
13 | console.log(numberIterator.next())
14 |
15 | // Hagamos un objeto que itere sobre las palabras de un string:
16 | class LoremIpsum {
17 | constructor(text) {
18 | this._text = text;
19 | }
20 |
21 | [Symbol.iterator]() {
22 | const re = /\S+/g;
23 | const text = this._text;
24 | return {
25 | next() {
26 | const match = re.exec(text);
27 | if(match) {
28 | return { value: match[0], done: false };
29 | }
30 | return { value: undefined, done: true };
31 | }
32 | }
33 | }
34 | }
35 |
36 | const lorem = new LoremIpsum('Lorem ipsum dolor sit amet, consectetur adipisicing elit. Unde voluptatem eveniet ipsum in similique maxime sunt eaque veritatis sapiente. Fuga minus, non cumque deleniti consequatur. Odit reprehenderit non fugit cum!');
37 |
38 | for (let word of lorem){
39 | console.log(word)
40 | }
41 |
42 | // Bonus: crea un array mediante spread a partir de un iterable
43 | console.log([...lorem])
44 | console.log(...lorem);
--------------------------------------------------------------------------------
/session-3/08_generators.js:
--------------------------------------------------------------------------------
1 | // Los generadores son funciones que pueden ser
2 | // pausadas y resumidas
3 | function* generatorFunction() {
4 | console.log('First');
5 | yield;
6 | console.log('Second');
7 | }
8 |
9 | // cuando llamamos a la función generador, no ejecuta
10 | // el cuerpo de la función, sino que devuelve un objeto generador:
11 | const generatorObject = generatorFunction();
12 |
13 | // El generador implementa una interfaz que le proporciona
14 | // un método next(), que ejecutará el cuerpo de la función
15 | // hasta encontrar un yield. En este punto, se detendrá.
16 | //
17 | // La función además devuelve un objeto de tipo:
18 | // {
19 | // value: el valor retornado por yield
20 | // done: indica si ha finalizado la ejecución del cuerpo de la función
21 | // }
22 | console.log(generatorObject.next());
23 |
24 | // Si volvemos a llamar, done valdrá true porque ya ha finalizado
25 | // la ejecución del cuerpo de la función
26 | console.log(generatorObject.next());
27 |
28 | // A partir de este punto, siempre valdrá true
29 | console.log(generatorObject.next());
30 |
31 | // Los generadores, al implementar .next(), son iterables
32 | function* abc() {
33 | yield 'a';
34 | yield 'b';
35 | yield 'c';
36 | }
37 |
38 | for (const char of abc()) {
39 | console.log(char);
40 | }
41 |
42 | const alphabet = [...abc()];
43 | console.log(alphabet);
44 |
45 | const [a, b, c] = abc();
46 | console.log(a);
47 | console.log(b);
48 | console.log(c);
49 |
50 | // Los generadores suelen ser una forma más sencilla de describir un iterador.
51 | // Volviendo al ejemplo de antes:
52 | class LoremIpsum {
53 | constructor(text) {
54 | this._text = text;
55 | }
56 |
57 | *words() {
58 | const re = /\S+/g;
59 | let match;
60 | while(match = re.exec(this._text)){
61 | yield match[0];
62 | }
63 | }
64 | }
65 |
66 | const lorem = new LoremIpsum('Lorem ipsum dolor sit amet, consectetur adipisicing elit. Unde voluptatem eveniet ipsum in similique maxime sunt eaque veritatis sapiente. Fuga minus, non cumque deleniti consequatur. Odit reprehenderit non fugit cum!');
67 |
68 | for (let word of lorem.words()){
69 | console.log(word)
70 | }
71 |
72 | class Users {
73 | constructor(people) {
74 | this._people = people;
75 | }
76 |
77 | *alias() {
78 | for (let person of this._people) {
79 | yield person.sex === 'M' ? `Mr. ${person.name}`
80 | : `Mrs. ${person.name}`;
81 | }
82 | }
83 | }
84 |
85 | const people = new Users([
86 | {sex: 'M', name: 'John' },
87 | { sex: 'W', name: 'Lucia' }
88 | ]);
89 |
90 | for (let person of people.alias()){
91 | console.log(person)
92 | }
93 |
--------------------------------------------------------------------------------
/session-3/README.md:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/session-3/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "session-3",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "babel-node"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "devDependencies": {
12 | "babel-cli": "^6.4.5",
13 | "babel-preset-es2015": "^6.3.13",
14 | "babel-preset-stage-2": "^6.3.13"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/session-4/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [ "es2015", "stage-2" ],
3 | "plugins": []
4 | }
--------------------------------------------------------------------------------
/session-4/00_string_methods.js:
--------------------------------------------------------------------------------
1 | const lorem = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Non, sint distinctio in perferendis temporibus quod, vitae, explicabo exercitationem labore deserunt repellat doloremque molestias tempora, consectetur facere cum obcaecati nihil libero!';
2 |
3 | console.log(lorem.startsWith('Lorem'));
4 | console.log(lorem.endsWith('libero!'));
5 | console.log(lorem.includes('dolor'));
6 |
7 | console.log(lorem.startsWith('ipsum', 6));
8 |
9 | console.log('x'.repeat(3));
--------------------------------------------------------------------------------
/session-4/01_Number_Math.js:
--------------------------------------------------------------------------------
1 | console.log(Number.isInteger(25)); // true
2 | console.log(Number.isInteger(25.0)); // true
3 | console.log(Number.isInteger(25.1)); // false
4 |
5 | console.log(Number.isNaN(NaN)) // false
--------------------------------------------------------------------------------
/session-4/02_array.js:
--------------------------------------------------------------------------------
1 | // El método Array.of() crea una nueva instancia Array
2 | // con un número variable de elementos pasados como argumento,
3 | // independientemente del número o del tipo.
4 |
5 | // La diferencia entre Array.of() y el constructor Array reside
6 | // en como maneja los parámetros de tipo entero: Array.of(42)
7 | // crea un array con un solo elemento, 42, mientras Array(42)
8 | // crea un array con 42 elementos, el cual, cada uno es de tipo undefined.
9 |
10 | let items = new Array(1, 2); // length is 2
11 | console.log(items.length); // 2
12 | console.log(items[0]); // 1
13 | console.log(items[1]); // 2
14 |
15 | items = new Array(2);
16 | console.log(items.length); // 2
17 | console.log(items[0]); // undefined
18 | console.log(items[1]); // undefined
19 |
20 | items = Array.of(2);
21 | console.log(items.length); // 1
22 | console.log(items[0]); // 2
23 |
24 |
25 | function doSomething(){
26 | console.log(arguments);
27 | console.log(typeof arguments);
28 | // arguments "parece un array, pero no lo es. Lo siguiente da error"
29 | // console.log(arguments.map(a => a));
30 |
31 | // Podemos convertirlo en un array con Array.from
32 | let args = Array.from(arguments);
33 | console.log(args.map(a => a));
34 | }
35 |
36 | doSomething(1, 2, 3);
37 |
38 |
39 |
40 | let numbers = [25, 30, 35, 40, 45];
41 |
42 | console.log(numbers.find(n => n > 33)); // 35
43 | console.log(numbers.findIndex(n => n > 33)); // 2
44 |
45 |
46 |
47 | let numbers = [1, 2, 3, 4];
48 | numbers.fill(1, 2);
49 | console.log(numbers.toString()); // 1,2,1,1
50 | numbers.fill(0, 1, 3);
51 | console.log(numbers.toString()); // 1,0,0,1
--------------------------------------------------------------------------------
/session-4/03_sets.js:
--------------------------------------------------------------------------------
1 | // Un set es una lista de valores que no puede contener
2 | // duplicados.
3 | let es5Set = {};
4 | es5Set.foo = true;
5 |
6 | // checking for existence
7 | if (es5Set.foo) {
8 | console.log('do something')
9 | }
10 |
11 | // Un set en ES6 se define de la forma siguiente:
12 | let set = new Set();
13 | set.add('foo');
14 | console.log(set.has('foo'));
15 |
16 | console.log(set.entries());
17 |
18 | set.forEach(v => console.log(v))
19 | for (let item of set) console.log(item);
20 |
21 | var myArray = ["value1", "value2", "value3"];
22 |
23 | // Use the regular Set constructor to transform an Array into a Set
24 | var mySet = new Set(myArray);
25 |
26 | console.log(mySet.has("value1")); // returns true
27 |
28 | // Use the spread operator to transform a set into an Array.
29 | console.log([...mySet]); // Will show you exactly the same Array as myArray
--------------------------------------------------------------------------------
/session-4/04_maps.js:
--------------------------------------------------------------------------------
1 | let course = new Map();
2 | course.set('title', 'Aprende ECMAScript 2015');
3 | course.set('sessions', 6);
4 |
5 | console.log([...course])
6 |
7 | console.log(course.get('title'));
8 | console.log(course.get('sessions'));
9 |
10 | let map = new Map(),
11 | key1 = {},
12 | key2 = {};
13 |
14 | map.set(key1, 5);
15 | map.set(key2, 42);
16 |
17 | console.log(map.get(key1));
18 | console.log(map.get(key2));
--------------------------------------------------------------------------------
/session-4/05_weak_sets.js:
--------------------------------------------------------------------------------
1 | // Los Sets podemos considerarlos Strong Sets,
2 | // ya que conservan la referencia a sus claves
3 | // aunque el objeto original sea eliminado
4 | let set = new Set(),
5 | key = {};
6 |
7 | set.add(key);
8 | console.log(set.size); // 1
9 |
10 | // eliminate original reference
11 | key = null;
12 |
13 | console.log(set.size); // 1
14 |
15 | // get the original reference back
16 | key = [...set][0];
17 |
18 | // Esto puede causar un memory leak, por ejemplo si
19 | // nuestro código se ejecuta en una página web que
20 | // mantiene un registro de elementos del DOM que
21 | // podrían ser eliminados por otro script
22 |
23 | // Un weak set es un tipo de set que solo almacena una
24 | // referencia "débil" al objeto
25 | let weakSet = new WeakSet();
26 | let weakKey = {};
27 |
28 | // add the object to the set
29 | weakSet.add(weakKey);
30 |
31 | console.log(weakSet.has(weakKey)); // true
32 |
33 | weakSet.delete(weakKey);
34 |
35 | console.log(weakSet.has(weakKey)); // false
36 |
--------------------------------------------------------------------------------
/session-4/06_weak_maps.js:
--------------------------------------------------------------------------------
1 | let map = new WeakMap();
2 | let element = {};
3 |
4 | map.set(element, "Original");
5 |
6 | let value = map.get(element);
7 | console.log(value); // "Original"
8 |
9 | // remove the element
10 | element = null;
11 |
12 | // the weak map is empty at this point
13 | console.log(map.get(element));
--------------------------------------------------------------------------------
/session-4/07_animation_es5.js:
--------------------------------------------------------------------------------
1 |
2 | /** ES5 example **/
3 | function runAnimation(position){
4 | console.log('Moving to position...', position);
5 | };
6 |
7 | runAnimation(0);
8 | setTimeout(function() {
9 | runAnimation(1);
10 | setTimeout(function() {
11 | runAnimation(2);
12 | }, 1000);
13 | }, 1000);
14 |
--------------------------------------------------------------------------------
/session-4/08_animation_promise.js:
--------------------------------------------------------------------------------
1 |
2 | /** ES6 Promises example **/
3 | function runAnimation(position){
4 | console.log('Moving to position...', position);
5 | };
6 |
7 | function delay(interval){
8 | return new Promise(function(resolve) {
9 | setTimeout(resolve, interval);
10 | });
11 | };
12 |
13 | runAnimation(0);
14 | delay(1000)
15 | .then(function() {
16 | runAnimation(1);
17 | return delay(1000);
18 | })
19 | .then(function() {
20 | runAnimation(2);
21 | });
22 |
--------------------------------------------------------------------------------
/session-4/09_animation_parallel.js:
--------------------------------------------------------------------------------
1 | function getRandomTimeout() {
2 | return Math.floor(Math.random() * (1 - 5) + 5) * 1000;
3 | };
4 |
5 | function animation(position){
6 | console.log('Moving to position', position);
7 | return new Promise(function(resolve) {
8 | setTimeout(resolve, getRandomTimeout());
9 | });
10 | };
11 |
12 | Promise.all([
13 | animation(1),
14 | animation(2),
15 | animation(3),
16 | animation(4),
17 | animation(5),
18 | animation(6),
19 | animation(7),
20 | animation(8)
21 | ]).then(function() {
22 | animation(9);
23 | });
24 |
--------------------------------------------------------------------------------
/session-4/10_promise.js:
--------------------------------------------------------------------------------
1 | const doPromise = () => {
2 | return new Promise((resolve, reject) => {
3 | // Do something
4 | if(error){
5 | reject(error);
6 | }
7 | // If succeeds
8 | resolve(result);
9 | });
10 | };
11 |
12 | let promiseResult = doPromise();
13 |
14 | promise.then((result) => {
15 | // fullfillment
16 | }).catch((err) => {
17 | // rejection
18 | });
--------------------------------------------------------------------------------
/session-4/README.md:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/session-4/modules/aliases.js:
--------------------------------------------------------------------------------
1 | function greet(text) {
2 | return text;
3 | }
4 |
5 | export { greet as saluda };
--------------------------------------------------------------------------------
/session-4/modules/app.js:
--------------------------------------------------------------------------------
1 | // import suma from './suma';
2 |
3 | // console.log(suma)
4 | // console.log(suma(2, 2));
5 |
6 | // // Cuando no usamos default (comentar
7 | // // el import anterior de suma)
8 | // import {suma, resta} from './suma';
9 | // console.log(suma);
10 | // console.log(resta);
11 |
12 | // // También podemos importarlo todo, y veremos
13 | // // la estructura del módulo
14 | import * as mathematics from './suma';
15 | console.log(mathematics.default);
16 |
17 | // // import variables
18 | // import {color, name, MAGIC_NUMBER} from './vars'
19 | // console.log(color, name, MAGIC_NUMBER)
20 |
21 | // // import an exported function as default
22 | // import multiplica from './mathematics'
23 | // console.log(multiplica(3, 2))
24 |
25 | // // import an aliased function
26 | // import {saluda} from './aliases'
27 | // console.log(saluda('hola'))
28 | // console.log(saluda)
29 |
30 |
31 | // // Si tiene una función como default, podemos:
32 | // import mathematics from './suma';
33 | // console.log(mathematics)
34 | // console.log(mathematics(2, 3))
35 |
36 | // import Persona from './persona'
37 | // var dani = new Persona('dani', 'de la Cruz')
38 | // console.log(dani)
--------------------------------------------------------------------------------
/session-4/modules/mathematics.js:
--------------------------------------------------------------------------------
1 | // define a function
2 | function multiplica(a, b) {
3 | return a * b;
4 | }
5 |
6 | // export later
7 | // export as default, when the module
8 | // itself represents the function
9 | export default multiplica;
--------------------------------------------------------------------------------
/session-4/modules/persona.js:
--------------------------------------------------------------------------------
1 | class Persona {
2 | constructor(name, surname){
3 | this._name = name;
4 | this._surname = surname;
5 | }
6 | };
7 |
8 | export default Persona;
--------------------------------------------------------------------------------
/session-4/modules/suma.js:
--------------------------------------------------------------------------------
1 | // export as default, when the module
2 | // itself represents the function
3 | // export default function(a, b) {
4 | // return a + b;
5 | // }
6 |
7 | // equivalent to previous example
8 | // function suma(a, b) {
9 | // return a + b;
10 | // }
11 |
12 | // export { suma as default };
13 |
14 | // // When we don't use default, the module
15 | // // is exported as an object that contains
16 | // // the exported function, as it may contain
17 | // // others
18 | export function suma(a, b) {
19 | return a + b;
20 | }
21 |
22 | // // Podemos exportar más de una función
23 | export function resta(a, b) {
24 | return a - b;
25 | }
26 |
27 | // o, exportar una de ellas como default:
28 | export default function multiplicacion(a, b){
29 | return a * b;
30 | }
--------------------------------------------------------------------------------
/session-4/modules/vars.js:
--------------------------------------------------------------------------------
1 | export var color = 'red';
2 | export let name = 'Daniel';
3 | export const MAGIC_NUMBER = 7;
4 |
5 | // this will cause a syntax error, since
6 | // export may only appear at the top level
7 | if(true) {
8 | export var error = 'this is a syntax error'
9 | }
--------------------------------------------------------------------------------
/session-4/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "session-4",
3 | "version": "1.0.0",
4 | "description": "## Módulos ### Organización del código en módulos ### Exportación y tipos #### default, etc #### Exportación como singleton ### Importación ### Alias ## New Math, Number, String, Object APIs ### Novedades en apis ## Estructuras de datos: Map, Set, WeakMap, WeakSet ### TODO ## Promises ### Sintaxis ### Ejemplos",
5 | "main": "00_string_methods.js",
6 | "scripts": {
7 | "start": "babel-node"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "devDependencies": {
13 | "babel-cli": "^6.4.5",
14 | "babel-preset-es2015": "^6.3.13",
15 | "babel-preset-stage-2": "^6.3.13"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/session-5/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [ "es2015", "stage-1" ],
3 | "plugins": [ 'transform-decorators-legacy' ]
4 | }
5 |
--------------------------------------------------------------------------------
/session-5/00_symbols.js:
--------------------------------------------------------------------------------
1 | // Un símbolo es un tipo de datos cuyos valores son únicos e inmutables
2 | var COLOR_RED = 'Red';
3 | var COLOR_ORANGE = 'Orange';
4 | var COLOR_YELLOW = 'Yellow';
5 | var COLOR_GREEN = 'Green';
6 | var COLOR_BLUE = 'Blue';
7 | var COLOR_VIOLET = 'Violet';
8 | var SKY_BLUE = 'Blue';
9 |
10 | function printColor(color){
11 | switch (color) {
12 | case COLOR_RED:
13 | console.log('Rojo');
14 | break;
15 | case COLOR_ORANGE:
16 | console.log('Naranja');
17 | break;
18 | case COLOR_YELLOW:
19 | console.log('Amarillo');
20 | break;
21 | case COLOR_GREEN:
22 | console.log('Verde');
23 | break;
24 | case COLOR_BLUE:
25 | console.log('Azul');
26 | break;
27 | case COLOR_VIOLET:
28 | console.log('Violeta');
29 | break;
30 | case SKY_BLUE:
31 | console.log('Azul cielo');
32 | break;
33 | default:
34 | throw new Exception('Unknown color: ' + color);
35 | }
36 | }
37 | printColor(COLOR_BLUE);
38 | printColor(SKY_BLUE);
39 |
40 | // Si lo convertimos a
41 | var COLOR_RED = Symbol();
42 | var COLOR_ORANGE = Symbol();
43 | var COLOR_YELLOW = Symbol();
44 | var COLOR_GREEN = Symbol();
45 | var COLOR_BLUE = Symbol();
46 | var COLOR_VIOLET = Symbol();
47 | var SKY_BLUE = Symbol();
48 |
49 | printColor(COLOR_BLUE);
50 | printColor(SKY_BLUE);
51 |
52 |
53 | console.log(Symbol('foo'));
54 | console.log(Symbol('foo').toString());
55 |
56 | // Los símbolos usados como claves de objeto no entrarán
57 | // en conflicto con otras claves
58 | var myObj = {};
59 | var fooSym = Symbol('foo');
60 | var otherSym = Symbol('bar');
61 | myObj['foo'] = 'bar';
62 | myObj[fooSym] = 'baz';
63 | myObj[otherSym] = 'bing';
64 | console.log(myObj.foo === 'bar');
65 | console.log(myObj[fooSym] === 'baz');
66 | console.log(myObj[otherSym] === 'bing');
67 |
68 | // Lo podemos utilizar como propiedades de una clase
69 | const _counter = Symbol();
70 |
71 | class Visits {
72 | constructor({counter = 0} = {}){
73 | this[_counter] = counter;
74 | }
75 |
76 | add(){
77 | let counter = this[_counter];
78 | counter ++;
79 | this[_counter] = counter;
80 | return this[_counter];
81 | }
82 | }
83 |
84 | let visits = new Visits();
85 | console.log(visits.add());
86 |
87 | // No aparecen enumerados como propiedades del objeto
88 | var fooSym = Symbol('foo');
89 | var myObj = {};
90 | myObj['foo'] = 'bar';
91 | myObj[fooSym] = 'baz';
92 | console.log(Object.keys(myObj)); // -> [ 'foo' ]
93 | console.log(Object.getOwnPropertyNames(myObj)); // -> [ 'foo' ]
94 | console.log(Object.getOwnPropertySymbols(myObj)); // -> [ Symbol(foo) ]
95 | console.log((Object.getOwnPropertySymbols(myObj)[0] === fooSym));
--------------------------------------------------------------------------------
/session-5/01_proxies.js:
--------------------------------------------------------------------------------
1 | require('harmony-reflect')
2 |
3 | /*
4 | Supported in node with:
5 | https://github.com/tvcutsem/harmony-reflect
6 | use node --harmony-proxies
7 | */
8 | const target = {};
9 | const handler = {
10 | get(target, propKey, receiver) {
11 | console.log(`get ${propKey}`);
12 | return 'hello';
13 | }
14 | }
15 |
16 | const proxy = new Proxy(target, handler);
17 |
18 | console.log(proxy.foo);
19 | // get foo
20 | // hello
--------------------------------------------------------------------------------
/session-5/02_reflection.js:
--------------------------------------------------------------------------------
1 |
2 | // Reflect.has
3 | var myObject = {
4 | foo: 1
5 | };
6 |
7 | console.log('foo' in myObject);
8 | console.log(Reflect.has(myObject, 'foo'));
--------------------------------------------------------------------------------
/session-5/03_decorators.js:
--------------------------------------------------------------------------------
1 | const readonly = (target, name, descriptor) => {
2 | descriptor.writable = false;
3 | return descriptor;
4 | };
5 |
6 | class Person {
7 | constructor({first, last}){
8 | this.first = first;
9 | this.last = last;
10 | }
11 |
12 | @readonly
13 | name() { return `${this.first} ${this.last}` }
14 | }
15 |
16 | const person = new Person({
17 | first: 'Dani',
18 | last: 'de la Cruz'
19 | });
20 |
21 | console.log(person.name());
22 | person.name = () => { return `${this.first}` }
--------------------------------------------------------------------------------
/session-5/README.md:
--------------------------------------------------------------------------------
1 | # Sesión 5: Conceptos avanzados
2 |
--------------------------------------------------------------------------------
/session-5/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "session-5",
3 | "version": "1.0.0",
4 | "description": "## Symbols ### Sintaxis ### Uso ## Proxies ## Reflection ### Explicar concepto de Reflection ### Por qué usar Reflect #### Valores de retorno más útiles #### Sintaxis menos verbosa #### Aplicación de funciones más fiable #### Constructores con un número arbitrario de argumentos ## Decoradores",
5 | "main": "00_symbols.js",
6 | "scripts": {
7 | "start": "babel-node"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "devDependencies": {
13 | "babel-cli": "^6.4.5",
14 | "babel-plugin-transform-decorators-legacy": "^1.3.4",
15 | "babel-preset-es2015": "^6.3.13",
16 | "babel-preset-stage-1": "^6.3.13",
17 | "harmony-reflect": "^1.4.2"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/session-6/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [ "es2015" ],
3 | "plugins": []
4 | }
--------------------------------------------------------------------------------
/session-6/README.md:
--------------------------------------------------------------------------------
1 | # Ejercicio práctico
2 | El objetivo del ejercicio consiste en mostrar una lista de recursos atacando a una API, en este caso la [API de Pokémon](http://pokeapi.co/) (aunque se puede escoger cualquier otra). Lo interesante del ejercicio es que nos hemos autoimpuesto la condición de **no utilizar nada de html** y tampoco **ninguna librería ni framework JS para crear componentes de UI**. Absolutamente todo el código debe estar escrito en JavaScript, cumpliendo el estándar ECMAScript 2015.
3 |
4 | ## Entorno de desarrollo
5 | Tanto para trabajar en local como para crear los assets de archivos estáticos para producción, vamos a utilizar [Webpack](https://webpack.github.io/). Puedes encontrar la configuración utilizada en el archivo `webpack.config.js`, con una configuración base en el objeto `common` y dos configuraciones que se combinan en función de la tarea de `npm` utilizada.
6 |
7 | En el caso del `packaje.json`, tenemos cuatro tareas:
8 | * `npm start`: Arranca webpack en modo desarrollo. Para ver tu página, accede a [http://localhost:3000/dist/main](http://localhost:3000/dist/main)
9 | * `npm run build`: Compila el código para distribuirlo en producción
10 | * `npm run clean`: Limpia la carpeta `dist`, en la que se generan los archivos en modo producción
11 | * `npm run fenix`: Limpia la carpeta `node_modules` y realiza una instalación limpia de todas las dependencias npm
12 |
--------------------------------------------------------------------------------
/session-6/dist/main.css:
--------------------------------------------------------------------------------
1 | .Card{margin:8px;position:relative;border-radius:2px;overflow:hidden;background-color:#fafafa;height:180px;width:130px;transition:box-shadow .25s;box-shadow:0 2px 5px 0 rgba(0,0,0,.16),0 2px 10px 0 rgba(0,0,0,.12)}.Card-content{padding:20px;border-radius:0 0 2px 2px}.Card-content p{margin:0;padding:0}.Card-title{line-height:10px;font-size:18px;font-weight:300}.Card-image{display:block;border-radius:2px 2px 0 0;position:relative;left:0;right:0;top:0;bottom:0;height:130px;width:100%}html{line-height:1.5;font-family:Roboto,sans-serif;font-weight:400;font-size:15px}body{display:flex;flex-flow:row wrap}a{text-decoration:none}
--------------------------------------------------------------------------------
/session-6/dist/main.js:
--------------------------------------------------------------------------------
1 | !function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return e[r].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var n={};return t.m=e,t.c=n,t.p="http://localhost:3000/dist",t(0)}([function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}var o=n(1),i=r(o),u=n(7),a=r(u);n(21),a["default"].get("pokemon_list_use_case").execute().then(function(e){return e.map(function(e){return new i["default"](e)})}).then(function(e){var t=!0,n=!1,r=void 0;try{for(var o,i=e[Symbol.iterator]();!(t=(o=i.next()).done);t=!0){var u=o.value;document.body.appendChild(u.render())}}catch(a){n=!0,r=a}finally{try{!t&&i["return"]&&i["return"]()}finally{if(n)throw r}}})},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var o=function(){function e(e,t){for(var n=0;ni;++i)n=o[i],t=n.split("="),r[decodeURIComponent(t[0])]=decodeURIComponent(t[1]);return r}function c(e){var t,n,r,o,i=e.split(/\r?\n/),u={};i.pop();for(var a=0,s=i.length;s>a;++a)n=i[a],t=n.indexOf(":"),r=n.slice(0,t).toLowerCase(),o=w(n.slice(t+1)),u[r]=o;return u}function l(e){return/[\/+]json\b/.test(e)}function f(e){return e.split(/ *; */).shift()}function p(e){return _(e.split(/ *; */),function(e,t){var n=t.split(/ *= */),r=n.shift(),o=n.shift();return r&&o&&(e[r]=o),e},{})}function h(e,t){t=t||{},this.req=e,this.xhr=this.req.xhr,this.text="HEAD"!=this.req.method&&(""===this.xhr.responseType||"text"===this.xhr.responseType)||"undefined"==typeof this.xhr.responseType?this.xhr.responseText:null,this.statusText=this.req.xhr.statusText,this.setStatusProperties(this.xhr.status),this.header=this.headers=c(this.xhr.getAllResponseHeaders()),this.header["content-type"]=this.xhr.getResponseHeader("content-type"),this.setHeaderProperties(this.header),this.body="HEAD"!=this.req.method?this.parseBody(this.text?this.text:this.xhr.response):null}function d(e,t){var n=this;v.call(this),this._query=this._query||[],this.method=e,this.url=t,this.header={},this._header={},this.on("end",function(){var e=null,t=null;try{t=new h(n)}catch(r){return e=new Error("Parser is unable to parse the response"),e.parse=!0,e.original=r,e.rawResponse=n.xhr&&n.xhr.responseText?n.xhr.responseText:null,n.callback(e)}if(n.emit("response",t),e)return n.callback(e,t);if(t.status>=200&&t.status<300)return n.callback(e,t);var o=new Error(t.statusText||"Unsuccessful HTTP response");o.original=e,o.response=t,o.status=t.status,n.callback(o,t)})}function y(e,t){return"function"==typeof t?new d("GET",e).end(t):1==arguments.length?new d("GET",e):new d(e,t)}function m(e,t){var n=y("DELETE",e);return t&&n.end(t),n}var b,v=n(19),_=n(20);b="undefined"!=typeof window?window:"undefined"!=typeof self?self:this,y.getXHR=function(){if(!(!b.XMLHttpRequest||b.location&&"file:"==b.location.protocol&&b.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(e){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(e){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(e){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(e){}return!1};var w="".trim?function(e){return e.trim()}:function(e){return e.replace(/(^\s*|\s*$)/g,"")};y.serializeObject=u,y.parseString=s,y.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},y.serialize={"application/x-www-form-urlencoded":u,"application/json":JSON.stringify},y.parse={"application/x-www-form-urlencoded":s,"application/json":JSON.parse},h.prototype.get=function(e){return this.header[e.toLowerCase()]},h.prototype.setHeaderProperties=function(e){var t=this.header["content-type"]||"";this.type=f(t);var n=p(t);for(var r in n)this[r]=n[r]},h.prototype.parseBody=function(e){var t=y.parse[this.type];return t&&e&&(e.length||e instanceof Object)?t(e):null},h.prototype.setStatusProperties=function(e){1223===e&&(e=204);var t=e/100|0;this.status=this.statusCode=e,this.statusType=t,this.info=1==t,this.ok=2==t,this.clientError=4==t,this.serverError=5==t,this.error=4==t||5==t?this.toError():!1,this.accepted=202==e,this.noContent=204==e,this.badRequest=400==e,this.unauthorized=401==e,this.notAcceptable=406==e,this.notFound=404==e,this.forbidden=403==e},h.prototype.toError=function(){var e=this.req,t=e.method,n=e.url,r="cannot "+t+" "+n+" ("+this.status+")",o=new Error(r);return o.status=this.status,o.method=t,o.url=n,o},y.Response=h,v(d.prototype),d.prototype.use=function(e){return e(this),this},d.prototype.timeout=function(e){return this._timeout=e,this},d.prototype.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},d.prototype.abort=function(){return this.aborted?void 0:(this.aborted=!0,this.xhr.abort(),this.clearTimeout(),this.emit("abort"),this)},d.prototype.set=function(e,t){if(i(e)){for(var n in e)this.set(n,e[n]);return this}return this._header[e.toLowerCase()]=t,this.header[e]=t,this},d.prototype.unset=function(e){return delete this._header[e.toLowerCase()],delete this.header[e],this},d.prototype.getHeader=function(e){return this._header[e.toLowerCase()]},d.prototype.type=function(e){return this.set("Content-Type",y.types[e]||e),this},d.prototype.parse=function(e){return this._parser=e,this},d.prototype.accept=function(e){return this.set("Accept",y.types[e]||e),this},d.prototype.auth=function(e,t){var n=btoa(e+":"+t);return this.set("Authorization","Basic "+n),this},d.prototype.query=function(e){return"string"!=typeof e&&(e=u(e)),e&&this._query.push(e),this},d.prototype.field=function(e,t){return this._formData||(this._formData=new b.FormData),this._formData.append(e,t),this},d.prototype.attach=function(e,t,n){return this._formData||(this._formData=new b.FormData),this._formData.append(e,t,n||t.name),this},d.prototype.send=function(e){var t=i(e),n=this.getHeader("Content-Type");if(t&&i(this._data))for(var r in e)this._data[r]=e[r];else"string"==typeof e?(n||this.type("form"),n=this.getHeader("Content-Type"),"application/x-www-form-urlencoded"==n?this._data=this._data?this._data+"&"+e:e:this._data=(this._data||"")+e):this._data=e;return!t||o(e)?this:(n||this.type("json"),this)},d.prototype.callback=function(e,t){var n=this._callback;this.clearTimeout(),n(e,t)},d.prototype.crossDomainError=function(){var e=new Error("Request has been terminated\nPossible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.");e.crossDomain=!0,e.status=this.status,e.method=this.method,e.url=this.url,this.callback(e)},d.prototype.timeoutError=function(){var e=this._timeout,t=new Error("timeout of "+e+"ms exceeded");t.timeout=e,this.callback(t)},d.prototype.withCredentials=function(){return this._withCredentials=!0,this},d.prototype.end=function(e){var t=this,n=this.xhr=y.getXHR(),i=this._query.join("&"),u=this._timeout,a=this._formData||this._data;this._callback=e||r,n.onreadystatechange=function(){if(4==n.readyState){var e;try{e=n.status}catch(r){e=0}if(0==e){if(t.timedout)return t.timeoutError();if(t.aborted)return;return t.crossDomainError()}t.emit("end")}};var s=function(e){e.total>0&&(e.percent=e.loaded/e.total*100),e.direction="download",t.emit("progress",e)};this.hasListeners("progress")&&(n.onprogress=s);try{n.upload&&this.hasListeners("progress")&&(n.upload.onprogress=s)}catch(c){}if(u&&!this._timer&&(this._timer=setTimeout(function(){t.timedout=!0,t.abort()},u)),i&&(i=y.serializeObject(i),this.url+=~this.url.indexOf("?")?"&"+i:"?"+i),n.open(this.method,this.url,!0),this._withCredentials&&(n.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof a&&!o(a)){var f=this.getHeader("Content-Type"),p=this._parser||y.serialize[f?f.split(";")[0]:""];!p&&l(f)&&(p=y.serialize["application/json"]),p&&(a=p(a))}for(var h in this.header)null!=this.header[h]&&n.setRequestHeader(h,this.header[h]);return this.emit("request",this),n.send("undefined"!=typeof a?a:null),this},d.prototype.then=function(e,t){return this.end(function(n,r){n?t(n):e(r)})},y.Request=d,y.get=function(e,t,n){var r=y("GET",e);return"function"==typeof t&&(n=t,t=null),t&&r.query(t),n&&r.end(n),r},y.head=function(e,t,n){var r=y("HEAD",e);return"function"==typeof t&&(n=t,t=null),t&&r.send(t),n&&r.end(n),r},y.del=m,y["delete"]=m,y.patch=function(e,t,n){var r=y("PATCH",e);return"function"==typeof t&&(n=t,t=null),t&&r.send(t),n&&r.end(n),r},y.post=function(e,t,n){var r=y("POST",e);return"function"==typeof t&&(n=t,t=null),t&&r.send(t),n&&r.end(n),r},y.put=function(e,t,n){var r=y("PUT",e);return"function"==typeof t&&(n=t,t=null),t&&r.send(t),n&&r.end(n),r},e.exports=y},function(e,t){function n(e){return e?r(e):void 0}function r(e){for(var t in n.prototype)e[t]=n.prototype[t];return e}e.exports=n,n.prototype.on=n.prototype.addEventListener=function(e,t){return this._callbacks=this._callbacks||{},(this._callbacks["$"+e]=this._callbacks["$"+e]||[]).push(t),this},n.prototype.once=function(e,t){function n(){this.off(e,n),t.apply(this,arguments)}return n.fn=t,this.on(e,n),this},n.prototype.off=n.prototype.removeListener=n.prototype.removeAllListeners=n.prototype.removeEventListener=function(e,t){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var n=this._callbacks["$"+e];if(!n)return this;if(1==arguments.length)return delete this._callbacks["$"+e],this;for(var r,o=0;or;++r)n[r].apply(this,t)}return this},n.prototype.listeners=function(e){return this._callbacks=this._callbacks||{},this._callbacks["$"+e]||[]},n.prototype.hasListeners=function(e){return!!this.listeners(e).length}},function(e,t){e.exports=function(e,t,n){for(var r=0,o=e.length,i=3==arguments.length?n:e[r++];o>r;)i=t.call(null,i,e[r],++r,e);return i}},function(e,t){}]);
--------------------------------------------------------------------------------
/session-6/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "session-6",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "webpack",
8 | "clean": "rimraf dist",
9 | "fenix": "rimraf node_modules && npm i",
10 | "start": "webpack-dev-server"
11 | },
12 | "keywords": [],
13 | "author": "",
14 | "license": "ISC",
15 | "devDependencies": {
16 | "babel-cli": "6.4.5",
17 | "babel-loader": "6.2.3",
18 | "babel-polyfill": "6.3.14",
19 | "babel-preset-es2015": "6.3.13",
20 | "css-loader": "0.23.1",
21 | "extract-text-webpack-plugin": "1.0.1",
22 | "node-sass": "^3.4.2",
23 | "rimraf": "2.5.2",
24 | "sass-loader": "^3.1.2",
25 | "style-loader": "0.13.0",
26 | "superagent": "^1.7.2",
27 | "webpack": "1.12.13",
28 | "webpack-dev-server": "1.14.1",
29 | "webpack-merge": "0.7.3"
30 | },
31 | "dependencies": {
32 | "underscore.string": "^3.2.3"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/session-6/src/components/card/_index.scss:
--------------------------------------------------------------------------------
1 | .Card {
2 | margin: 8px;
3 | position: relative;
4 | border-radius: 2px;
5 | overflow: hidden;
6 | background-color: #fafafa;
7 | height: 180px;
8 | width: 130px;
9 | transition: box-shadow .25s;
10 | box-shadow: 0 2px 5px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12);
11 |
12 | &-content {
13 | padding: 20px;
14 | border-radius: 0 0 2px 2px;
15 |
16 | p {
17 | margin: 0;
18 | padding: 0;
19 | }
20 | }
21 |
22 | &-title {
23 | line-height: 10px;
24 | font-size: 18px;
25 | font-weight: 300;
26 | }
27 |
28 | &-image {
29 | display: block;
30 | border-radius: 2px 2px 0 0;
31 | position: relative;
32 | left: 0;
33 | right: 0;
34 | top: 0;
35 | bottom: 0;
36 | height: 130px;
37 | width: 100%;
38 | }
39 | }
--------------------------------------------------------------------------------
/session-6/src/components/card/index.js:
--------------------------------------------------------------------------------
1 | import {Image, Div, Text, HtmlComponent} from '../html';
2 |
3 | class Card extends HtmlComponent {
4 | constructor({name, image} = {}){
5 | super({name, image});
6 | this._name = name;
7 | this._image = image;
8 | }
9 |
10 | render() {
11 | const card = new Div('Card');
12 | const cardContent = new Div('Card-content');
13 | const title = new Div('Card-title');
14 | const image = new Image({className: 'Card-image', src: this._image});
15 | const name = new Text({text: this._name});
16 |
17 | title.appendChild(name);
18 | cardContent.appendChild(title);
19 | card.appendChild(image);
20 | card.appendChild(cardContent);
21 |
22 | return card.render();
23 | }
24 | };
25 |
26 | export default Card;
27 |
--------------------------------------------------------------------------------
/session-6/src/components/html/div.js:
--------------------------------------------------------------------------------
1 | import HtmlComponent from './htmlComponent';
2 |
3 | export default class Div extends HtmlComponent {
4 | constructor(className){
5 | super(className);
6 | this._className = className;
7 | this._children = new Set();
8 | }
9 |
10 | appendChild(element){
11 | this._children.add(element);
12 | }
13 |
14 | render(){
15 | const div = document.createElement('div');
16 | div.className = this._className;
17 |
18 | for(let child of this._children){
19 | console.log(child)
20 | div.appendChild(child.render())
21 | }
22 |
23 | return div;
24 | }
25 | }
--------------------------------------------------------------------------------
/session-6/src/components/html/htmlComponent.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @interface
3 | **/
4 | export default class HtmlComponent {
5 | render(){
6 | throw new Error('You must implement the render() method');
7 | }
8 | }
--------------------------------------------------------------------------------
/session-6/src/components/html/image.js:
--------------------------------------------------------------------------------
1 | import HtmlComponent from './htmlComponent';
2 |
3 | export default class Image extends HtmlComponent {
4 | constructor({className, src}) {
5 | super({className, src});
6 | this._src = src;
7 | this._className = className;
8 | }
9 |
10 | render() {
11 | const img = document.createElement('img');
12 | const src = document.createAttribute('src');
13 | src.value = `http://pokeapi.co/${this._src}`;
14 | img.setAttributeNode(src);
15 | img.className = this._className;
16 | return img;
17 | }
18 | };
--------------------------------------------------------------------------------
/session-6/src/components/html/index.js:
--------------------------------------------------------------------------------
1 | import Image from './image';
2 | import Div from './div';
3 | import Text from './text';
4 | import HtmlComponent from './htmlComponent';
5 |
6 | export {Image, Div, Text, HtmlComponent};
--------------------------------------------------------------------------------
/session-6/src/components/html/text.js:
--------------------------------------------------------------------------------
1 | import HtmlComponent from './htmlComponent';
2 |
3 | export default class Text extends HtmlComponent {
4 | constructor({text}){
5 | super({text});
6 | this._text = text;
7 | }
8 |
9 | render(){
10 | return document.createTextNode(this._text);
11 | }
12 | }
--------------------------------------------------------------------------------
/session-6/src/domain/entity.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @interface
3 | * */
4 | export default class Entity {}
5 |
--------------------------------------------------------------------------------
/session-6/src/domain/factories/pokemon.js:
--------------------------------------------------------------------------------
1 | import PokemonListUseCase from '../pokemon/pokemonListUseCase';
2 | import ApiPokemonRepository from '../pokemon/apiPokemonRepository';
3 | import PokemonEntity from '../pokemon/pokemonEntity';
4 | import SpriteEntity from '../pokemon/spriteEntity';
5 | import superagent from 'superagent';
6 |
7 | export default class PokemonFactory {
8 |
9 | static pokemonListUseCase() {
10 | return new PokemonListUseCase({repository: PokemonFactory.apiPokemonRepository()});
11 | }
12 |
13 | static apiPokemonRepository() {
14 | return new ApiPokemonRepository(PokemonFactory.fetcher());
15 | }
16 |
17 | static fetcher(){
18 | return superagent;
19 | }
20 |
21 | static pokemonEntity({name, resource_uri, sprites} = {}){
22 | return new PokemonEntity({
23 | name,
24 | resource_uri,
25 | sprites: sprites && sprites.map(PokemonFactory.spriteEntity)
26 | });
27 | }
28 |
29 | static spriteEntity({id, resource_uri, image, pokemon}){
30 | return new SpriteEntity({id, resource_uri, image, pokemon: PokemonFactory.pokemonEntity(pokemon)});
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/session-6/src/domain/index.js:
--------------------------------------------------------------------------------
1 | import PokemonFactory from './factories/pokemon';
2 |
3 | class Pokedex {
4 | constructor(){
5 | this._deps = new Map();
6 |
7 | this._deps.set('pokemon_list_use_case', PokemonFactory.pokemonListUseCase());
8 | }
9 |
10 | get(key) {
11 | if(this._deps.has(key))
12 | return this._deps.get(key);
13 | console.warn(`Service ${key} is not implemented in the current version of the domain`);
14 | }
15 | }
16 |
17 | export default new Pokedex();
18 |
--------------------------------------------------------------------------------
/session-6/src/domain/pokemon/apiPokemonRepository.js:
--------------------------------------------------------------------------------
1 | import PokemonRepository from './pokemonRepository';
2 | import PokemonFactory from '../factories/pokemon';
3 |
4 | /**
5 | * @implements PokemonRepository
6 | * */
7 | export default class ApiPokemonRepository extends PokemonRepository {
8 | constructor(fetcher){
9 | super(fetcher);
10 | this._fetcher = fetcher;
11 | }
12 |
13 | list({query = ''} = {}) {
14 | return new Promise((resolve, reject) => {
15 | this._fetcher.get('http://pokeapi.co/api/v1/pokemon')
16 | .query({ limit: 20 })
17 | .end((err, resp) => {
18 | if(err){
19 | reject(err);
20 | return;
21 | }
22 | try {
23 | resolve(JSON.parse(resp.text).objects.map(PokemonFactory.pokemonEntity))
24 | } catch(err) { reject(err); }
25 | });
26 | });
27 | };
28 |
29 | sprite({resource_uri} = {}){
30 | return new Promise((resolve, reject) => {
31 | this._fetcher.get(`http://pokeapi.co${resource_uri}`)
32 | .end((err, resp) => {
33 | if(err) {
34 | reject(err);
35 | return;
36 | }
37 | try {
38 | resolve(PokemonFactory.spriteEntity(JSON.parse(resp.text)));
39 | } catch(err) { reject(err); }
40 | })
41 | });
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/session-6/src/domain/pokemon/pokemonEntity.js:
--------------------------------------------------------------------------------
1 | import Entity from '../entity';
2 | import capitalize from 'underscore.string/capitalize';
3 |
4 | export default class PokemonEntity extends Entity {
5 | constructor({name, resource_uri, sprites} = {}){
6 | super({name, resource_uri});
7 |
8 | this._name = name;
9 | this.resource_uri = resource_uri;
10 | this.sprites = sprites;
11 | }
12 |
13 | get name() {
14 | return capitalize(this._name);
15 | }
16 |
17 | set image(value) {
18 | this._image = value;
19 | }
20 |
21 | get image() {
22 | return this._image;
23 | }
24 | }
--------------------------------------------------------------------------------
/session-6/src/domain/pokemon/pokemonListUseCase.js:
--------------------------------------------------------------------------------
1 | import UseCase from '../useCase';
2 |
3 | /**
4 | * @implements UseCase
5 | * */
6 | export default class PokemonListUseCase extends UseCase {
7 |
8 | constructor({repository} = {}) {
9 | super(repository);
10 | this.repository = repository;
11 | }
12 |
13 | execute({query = ''} = {}) {
14 | return new Promise((resolve, reject) => {
15 | this.repository.list({query})
16 | .then((pokemons) => {
17 | Promise.all(pokemons.map(pokemon =>
18 | this.repository.sprite({resource_uri: pokemon.sprites[0].resource_uri})
19 | ))
20 | .then((sprites) => {
21 | return pokemons.map(pokemon => {
22 | pokemon.image = sprites.filter(s => s.pokemon.resource_uri === pokemon.resource_uri)[0].image;
23 | return pokemon;
24 | })
25 | })
26 | .then(pokemons => {
27 | resolve(pokemons);
28 | })
29 | })
30 | });
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/session-6/src/domain/pokemon/pokemonRepository.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @interface
3 | * */
4 | export default class PokemonRepository {
5 | list({query = ''} = {}) {
6 | throw new Error('PokemonRepository#list must be implemented');
7 | }
8 |
9 | sprite({resource_uri} = {}){
10 | throw new Error('PokemonRepository#sprite must be implemented');
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/session-6/src/domain/pokemon/spriteEntity.js:
--------------------------------------------------------------------------------
1 | import Entity from '../entity';
2 |
3 | export default class SpriteEntity extends Entity {
4 | constructor({id, image, resource_uri, pokemon} = {}) {
5 | super({id, image, resource_uri, pokemon});
6 | this.id = id;
7 | this.image = image;
8 | this.resource_uri = resource_uri;
9 | this.pokemon = pokemon;
10 | }
11 | }
--------------------------------------------------------------------------------
/session-6/src/domain/useCase.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @interface
3 | * */
4 | export default class Service {
5 | execute() {
6 | throw new Error('Service#execute must be implemented');
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/session-6/src/index.js:
--------------------------------------------------------------------------------
1 | import Card from './components/card';
2 | import Pokedex from './domain';
3 | import './index.scss';
4 |
5 | Pokedex.get('pokemon_list_use_case')
6 | .execute()
7 | .then((pokemons) => {
8 | return pokemons.map(p => new Card(p))
9 | })
10 | .then((cards) => {
11 | for(let card of cards) {
12 | document.body.appendChild(card.render());
13 | }
14 | });
--------------------------------------------------------------------------------
/session-6/src/index.scss:
--------------------------------------------------------------------------------
1 | @import './components/card/index';
2 |
3 | html {
4 | line-height: 1.5;
5 | font-family: "Roboto", sans-serif;
6 | font-weight: normal;
7 | font-size: 15px;
8 | }
9 |
10 | body {
11 | display: flex;
12 | flex-flow: row wrap;
13 | }
14 |
15 | a {
16 | text-decoration: none;
17 | }
--------------------------------------------------------------------------------
/session-6/webpack.config.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 | var webpack = require('webpack');
3 | var ExtractTextPlugin = require('extract-text-webpack-plugin');
4 | var merge = require('webpack-merge');
5 |
6 | var APP_PATH = path.join(__dirname, '/src');
7 | var TARGET = process.env.npm_lifecycle_event;
8 |
9 | var common = {
10 | context: APP_PATH,
11 | entry: './',
12 | output: {
13 | path: path.join(__dirname, 'dist'),
14 | filename: '[name].js',
15 | publicPath: 'http://localhost:3000/dist'
16 | },
17 | module: { loaders: [{
18 | test: /\.js$/,
19 | loaders: [ 'babel' ],
20 | exclude: /node_modules/
21 | }] },
22 | plugins: []
23 | };
24 |
25 | if(TARGET === 'start' || !TARGET) {
26 | module.exports = merge(common, {
27 | devServer: {
28 | port: 3000,
29 | stats: { colors: true },
30 | inline: true,
31 | publicPath: '/dist/'
32 | },
33 | module: {
34 | loaders: [{
35 | test: /\.s?css$/,
36 | loaders: [ 'style-loader', 'css-loader', 'sass-loader' ],
37 | include: APP_PATH
38 | }]
39 | },
40 | plugins: [
41 | new webpack.HotModuleReplacementPlugin()
42 | ]
43 | });
44 | }
45 |
46 | if(TARGET === 'build') {
47 | module.exports = merge(common, {
48 | module: {
49 | loaders: [{
50 | test: /\.s?css$/,
51 | loader: ExtractTextPlugin.extract('css!sass'),
52 | include: APP_PATH
53 | }]
54 | },
55 | plugins: [
56 | new ExtractTextPlugin('[name].css', {
57 | allChunks: true
58 | }),
59 | new webpack.optimize.UglifyJsPlugin({
60 | compress: {
61 | warnings: false
62 | }
63 | })
64 | ]
65 | });
66 | }
67 |
--------------------------------------------------------------------------------