myIndexOf()
Implement the JavaScript native function myIndexOf()
The myIndexOf()
method returns the index within the calling String object of the first occurrence of the specified value, starting the search at fromIndex , returns -1 if the value is not found. The indexOf method is case sensitive.
Parameter | Description |
---|---|
searchValue |
A string representing the value to search for. |
fromIndex |
The location within the calling string to start the search from. It can be any integer between 0 and the length of the string. The default value is 0. |
myIndexOf()
Create a useful model of a standard 52-card deck of cards:
I should be able to draw a poker hand (5 card draw, not Texas hold 'em) and identify useful properties of the hand :
var x = 'Hello World';
function foo(){
var x;
alert( x );
x = 'New Value';
alert( x );
}
foo();
¿Qué devolveran los alert? ¿Por qué?
function test() {
foo();
bar();
var foo = function () {
alert("this won't run!");
}
function bar() {
alert("this will run!");
}
}
test();
¿Qué devolverá la ejecución de test? ¿Por qué?
var a = 1;
function f() {
var a = 2;
function n() {
alert(a);
}
n();
}
f();
¿Qué nos mostrará este código en el alert()? ¿Por qué?
Do the following exercises to practice closures http://nathansjslessons.appspot.com/lesson?id=1000
var mathy = function(x) {
return function (y) {
return function (z) {
return (x / y) - z;
}
}
}
¿Cómo hariamos la operación (4 / 3) - 2
con este código en una linea?
var superGreeter = function(greeting) {
return function(place) {
return function(nickname) {
return function(name) {
return greeting + ', ' + name + '! Welcome to ' + place + ', ' + nickname + '.';
}
}
}
};
superGreeter('Hey')('Berlin')('old pal')('Hans')
//'Hey, Hans! Welcome to Berlin, old pal.'
hiParisBuddyGreeter = superGreeter('Hi')('Paris')('buddy');
helloTokyoGreeter = superGreeter('Hello')('Tokyo');
hiParisBuddyGreeter('Franz')
//'Hi, Franz! Welcome to Paris, buddy.'
helloTokyoGreeter('friend')
//[Function]
helloTokyoGreeter('friend')('Yuki')
//'Hello, Yuki! Welcome to Tokyo, friend.'
Follow the steps on this repository to see the workflow of some functional programming code
Do the exercises 1-27 to practice functional programming
function F() {
function C() {
return this;
}
return C();
}
var o = new F();
¿El valor de this se referirá al objeto global o al objeto o?
function C(){
this.a = 1;
return false;
}
console.log(typeof new C());
¿Cuál es el resultado de ejecutar este trozo de código?
var add = function (x, y) {
this.val = x + y;
},
obj = { val: 0 };
add.apply(obj, [2, 8]);
console.log(obj.val);
¿Qué devolverá el console.log
? ¿A quien apunta this
al llamar add ?
var myObject = {
func1:function() {
console.log(this);
varfunc2 = function() {
console.log(this);
varfunc3=function() {
console.log(this);
}();
}();
}
};
myObject.func1();
¿Qué devolverá la ejecución de myObject.func1
? ¿Por qué?
var myObject = {
myProperty:'Icanseethelight',
myMethod:function() {
var that=this;
var helperFunction = function() {
console.log(that.myProperty);
console.log(this);
}();
}
}
myObject.myMethod();
¿Qué devolverá la ejecución de myObject.myMethod
? ¿Por qué?
Do the following KOAN to practice javascript concepts
Do the following exercises and then let's share and comment the solutions
Do the following KOAN to assure the understanding of jquery concepts
For this section you need to install at your machine the following:
npm install -g yo bower grunt-cli
Steps:
npm install
grunt
$ git --version
$ node -v
$ npm -v
$ npm install -g grunt-cli
$ git clone git@github.com:juanmaguitar/training-js-vueling.git
$ cd training-js-vueling
$ npm install
$ grunt --version
$ grunt -h
$ grunt tasks
$ grunt compass
$ grunt shower
$ grunt serve
Steps:
package.json
interactively with npm init
Gruntfile.js
(simple task, no plugin loading).
├── Gruntfile.js
├── package.json
$ mkdir project
$ cd project/
$ mkdir src
$ npm init
$ npm install --save-dev grunt
$ vi Gruntfile.js
module.exports = function(grunt) {
grunt.registerTask('foo', function() {
grunt.log.writeln('foo is running...');
});
};
$ grunt foo
npm install -g grunt-cli
npm install --save-dev grunt grunt-contrib-jshint
npm install
package.json
: The Grunt runner and Grunt plugins used in the Gruntfile.js are set as project dependencies in this fileGruntfile.js
: The tasks are defined/configured and grunt plugins are loaded in this file {
"name": "my-project-name",
"version": "0.1.0",
"devDependencies": {
"grunt": "~0.4.5",
"grunt-contrib-jshint": "~0.10.0",
"grunt-contrib-nodeunit": "~0.4.1",
"grunt-contrib-uglify": "~0.5.0"
}
}
Gruntfile.js
:module.exports = function(grunt) {
grunt.initConfig({
jshint: {
files: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'],
options: {
globals: {
jQuery: true
}
}
},
watch: {
files: ['<%= jshint.files %>'],
tasks: ['jshint']
}
});
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['jshint']);
};
Steps:
package.json
interactively with npm init
grunt
& grunt-contrib-jshint
)Gruntfile.js
(as defined here).
├── Gruntfile.js
├── package.json
└── src
└── foo.js
$ mkdir project2
$ cd project2/
$ mkdir src
$ npm init
$ npm install --save-dev grunt grunt-contrib-jshint
$ vi Gruntfile.js
module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.initConfig({
jshint: {
options: {
curly: true,
eqeqeq: true
},
target1: ['Gruntfile.js', 'src/**/*.js']
}
});
grunt.registerTask('default', ['jshint']);
};
$ grunt
grunt.initConfig({...})
→ Configuration objectgrunt.initConfig({
pkg: grunt.file.readJSON('package.json')
uglify: {
options: {
// the banner is inserted at the top of the output
banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
},
dist: {
files: {
'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
}
}
}
});
grunt.loadNpmTasks(...);
→ Load the Grunt plugins.grunt.loadNpmTasks("grunt-contrib-uglify");
grunt.registerTask(...);
→ Aliases for already loaded/created tasksgrunt.registerTask('default', ['jshint', 'qunit', 'concat', 'uglify']);
├── Gruntfile.js
├── dist
├── index.html
├── package.json
├── src
│ ├── js
│ │ ├── bar.js
│ │ └── foo.js
│ ├── scss
│ │ └── styles.scss
│ └── vendor
│ └── jquery-2.1.3.js
└── test
├── barSpec.js
└── fooSpec.js
Given the previous structure, create a Grunt project that provides the following tasks:
grunt concat
→ concatenate all .js files at src folder (using ;
as separator) in a npm-project-named .js file placed at dist folder
grunt uglify
→ uglify file generated by concat task into a new .min.js file placed at dist foldergrunt jshint
→ validate the js code (Gruntfile.js, src/js, test)grunt compass
→ compile src/styles.scss file into a dist/styles.cssgrunt
or grunt default
→ launches all previous tasks (jshint, concat, uglify, compass)grunt watch
→ watch any change done at Gruntfile.js or src folder and launches default task w/ new changesgrunt jasmine
→ launch all jasmine tests at test folder (add it to default task)grunt serve
→ launch a local server at localhost:8081 (after launching default task)Also, prepare the project w/ the following:
package.json
→ add here all grunt dependencies (you can test if this works by removing the node_modules
folder, launching npm install
and test that all grunt tasks work properly )bower.json
→ remove the folder vendor
and add jquery as a bower dependency. Modify the grunt tasks if necessary.livereload
→ prepare your watch grunt tasks to reload the page in the browser automatically when detect changes=>
this
Four versions:
(arg1, arg2, ...) => expr
(arg1, arg2, ...) => { stmt1; stmt2; ... }
singleArg => expr
singleArg => { stmt1; stmt2; ... }
BEFORE (ES5)
var self = this;
this.element.addEventListener('click', function(event) {
self.registerClick(event.target.id);
});
AFTER (ES2015)
this.element.addEventListener('click', event => {
this.registerClick(event.target.id);
});
BEFORE (ES5)
[1,3,4,5,6,7].filter(function(n) { return n % 2 } )
.map(function(n, i) { return n + i } );
// [1, 4, 7, 10]
AFTER (ES2015)
[1,2,3,4,5,6,7].filter(n => n % 2).map((n, i) => n+i);
Do the following katas to assure the understanding of arrow functions
BEFORE (ES5)
var arr = [1, 2, 3];
for (var i = 0; i < arr.length; i++) {
// i from 0 to 2
}
i; // 3
{
var TEMPERATURE = 32;
TEMPERATURE = 16;
TEMPERATURE // 16
}
TEMPERATURE; // 16
AFTER (ES2015)
var arr = [1, 2, 3];
for (let i = 0; i < arr.length; i++) {
// i from 0 to 2
}
i; // ReferenceError: i is not defined!
{
const TEMPERATURE = 32;
TEMPERATURE = 16;
TEMPERATURE; // 32
}
TEMPERATURE; // ReferenceError: TEMPERATURE is not defined!
Do the following katas to assure the understanding of Block Scope
``
${ expression }
`string text`
`string text line 1
string text line 2`
`string text ${expression} string text`
BEFORE (ES5)
var name = "juanma";
var getSuitableDrink = function(who) {
return who === 'juanma' ? 'beer' : 'cocktail'
};
console.log( 'Hello, '+name+'!\nFancy a '+getSuitableDrink()+'?' );
// Hello, juanma!
// Fancy a beer?
AFTER (ES2015)
var name = "juanma";
var getSuitableDrink = function(who) {
return who === 'juanma' ? 'beer' : 'cocktail'
};
console.log( `Hello, ${ name }!
Fancy a ${ getSuitableDrink() }?` );
Do the following katas to assure the understanding of template strings
var a = "foo",
b = 42,
c = {};
function myMethod() {
console.log('ooOoh!');
}
// Shorthand property names
var o = { a, b, c };
// Shorthand method name and dynamic property name
var o2 = {
myMethod,
['myPropertyNum'+b]: 'bar'
}
var messages = {
get latest () {
if (this.log.length == 0) return undefined;
return this.log[this.log.length - 1]
},
set current (str) {
this.log[this.log.length] = str;
},
log: []
}
messages.current = "hey!";
messages.latest // hey!
Do the following katas to assure the understanding of Enhanced Object Literals
function f(x, y=12) {
// y is 12 if not passed (or passed as undefined)
return x + y;
}
f(3) === 15;
f(3, undefined) === 15;
Do the following katas to assure the understanding of Default parameters
var [first, second, third, , fifth = 5] = [1, 2];
first // 1
second // 2
third // undefined
fifth // 5
[second, first] = [first, second] // swap values
first // 2
second // 1
var customer = {
name: 'John',
surname: 'Doe',
dateOfBirth: {
year: 1988
}
};
var {name, surname, dateOfBirth: {year}, children} = customer;
name // 'John'
surname // 'Doe'
year // 1988
children // undefined
...
function multiply(multiplier, ...numbers) {
return numbers.map(n => multiplier * n);
}
var arr = multiply(2, 1, 2, 3);
console.log(arr); // [2, 4, 6]
Do the following katas to assure the understanding of Rest operator
function f(x, y, z) {
return x + y + z;
}
var arr = [1, 2, 3];
f(...arr) === 6; // true
[0, ...arr, 4, 5, 6, 7]; // [0, 1, 2, 3, 4, 5, 6, 7]
Do the following katas to assure the understanding of Spread operator
Set
var s = new Set();
s.add("hello").add("goodbye").add("hello");
s.size === 2;
s.has("hello") === true;
s.delete("hello");
s.has("hello") === false;
Do the following katas to assure the understanding of Set
Map
var m = new Map();
m.set("hello", 42);
m.get("hello") === 42;
var s = { n:4 };
m.set(s, 34);
m.get(s) === 34;
var myMap = new Map();
var keyString = "a string",
keyObj = {},
keyFunc = function () {};
// setting the values
myMap.set(keyString, "value associated with 'a string'");
myMap.set(keyObj, "value associated with keyObj");
myMap.set(keyFunc, "value associated with keyFunc");
myMap.size; // 3
// getting the values
myMap.get(keyString); // "value associated with 'a string'"
myMap.get(keyObj); // "value associated with keyObj"
myMap.get(keyFunc); // "value associated with keyFunc"
myMap.get("a string"); // "value associated with 'a string'"
// because keyString === 'a string'
myMap.get({}); // undefined, because keyObj !== {}
myMap.get(function() {}) // undefined, because keyFunc !== function () {}
class
and extends
keywordsconstructor
definitionstatic
method definitionsBEFORE
var Shape = function( id, x, y ) {
this.id = id;
this.x = x;
this.y = y;
};
Shape.prototype.toString = function( x, y ) {
return "Shape(" + this.id + ")"
};
var Rectangle = function( id, x, y, width, height ) {
Shape.call( this, id, x, y );
};
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;
Rectangle.prototype.toString = function() {
return "Rectangle > " + Shape.prototype.toString.call( this );
};
AFTER
class Shape {
constructor (id, x, y) {
this.id = id;
this.x = x;
this.y = y;
// or Object.assign(this, {id, x, y});
}
toString () {
return `Shape(${this.id})`
}
}
class Rectangle extends Shape {
constructor (id, x, y, width, height) {
super(id, x, y)
}
toString () {
return "Rectangle > " + super.toString()
}
}
Do the following katas to assure the understanding of Classes
// -------- jquery.js --------
export default function jQuery() {
/* code */
}
// -------- code.js --------
import $ from 'jquery';
$('body').addClass('yay');
// --------- http.js --------
export function get(url) {
/* code */
}
export function post(url, body) {
/* code */
}
// -------- code.js --------
import { get, post } from 'http';
import { TIMEOUT as HTTP_TIMEOUT } from 'http';
import * as http from 'http';
get('/my/url').then(function(result) {
/* code */
});
HTTP_TIMEOUT; // 1000;
http.post('/my/url', 'body');
Array object extended with:
from()
, of()
copyWithin()
, entries()
, fill()
, find()
, findIndex()
, keys()
, values()
Array.from(arguments) // [].slice.call(arguments);
Array.from({0: 'hello', 1: world, length: 2}); // ['hello', 'world']
Array.of(1, 2, 3) // [1, 2, 3]
[1, 2, 3, 4, 5].copyWithin(0, 3, 4) // [4, 2, 3, 4, 5]
[1, 2, 3].fill(4) // [4, 4, 4]
[4, 5, 8, 12].find(isPrime) // 5
[4, 5, 8, 12].findIndex(isPrime) // 2
[4, 5, 8, 12].keys() // iterator from 0 to 3
[4, 5, 8, 12].values() // iterator from 4 to 12
Do the following katas to assure the understanding of Array
String object extended with:
raw()
startsWith()
, endsWith()
, includes()
, repeat()
, ...String.raw`Line 1\nLine 2\nLine 3` // 'Line 1\\nLine 2\\nLine 3'
'Hello world'.startsWith('Hello') // true
'Hello world'.endsWith('world') // true
'Hello world'.includes('orl') // true
'Hello world'.repeat(2) // 'Hello worldHello world'
var promise = new Promise(function(resolve, reject) {
// Do something asynchronous and call resolve with the
// result or reject with the error
});
promise.then(function(result) {
// Use the result of the async call
}, function(error) {
// Process the error
});
var allPromise = Promise.all([getLocation, getTemperature]);
allPromise.then(function(location, temperature) {
console.log('The location is ', location,
'and the temperature is', temperature);
}, function(error) {
// Process the error
});
var racePromise = Promise.race([getGoogleAds, getYahooAds, getBindAds]);
racePromise.then(function(ads) {
page.addAds(ads);
});
Do the following katas to assure the understanding of Promise
Steps:
src
folder $ git clone https://github.com/juanmaguitar/project-es2015-webpack-umd.git
$ cd project-es2015-webpack-umd
$ npm install
$ npm start
$ node dist/project-babel-webpack.js
$ open "index.html"
Steps:
src
folder $ git clone https://github.com/juanmaguitar/project-es2015-systemJs.git
$ cd project-es2015-systemJs
$ npm install
$ grunt serve
Steps:
$ git clone https://github.com/juanmaguitar/webpack-multiple-entry-points.git
$ cd webpack-multiple-entry-points
$ npm install
$ npm start