JavaScript

Занятие 2

18 Feb 2017

skill-branch.ru/backend-middle

Профессия
Node.js & React.js developer
продвинутый курс

1

RegExp

Символы

abc…	Буквы
123…	Цифры
\d      Любые цифры
\D      Любые не цирфы
\w      Любые букво-цифры
\W      Любые не букво-цифры
\s      Любой пробельный символ
\S      Любой не пробельный символ

1

Множества

.	Any Character
[abc]	Only a, b, or c
[^abc]	Not a, b, nor c
[a-z]	Characters a to z
[0-9]	Numbers 0 to 9
[\wА-Яа-яЁё]*

1

Множества

{m}	m Repetitions
{m,n}	m to n Repetitions
*	Zero or more repetitions
+	One or more repetitions
?	Optional character
\+?  7?  \s  [0-9]{3}  \s  [0-9]{7}

1

Старт финиш


^...    Начало строки
...$    Конце строки
^...$	От начала до конца

1

Захват паттерна

(...)	Capture Group
(a(bc))	Capture Sub-group
(.*)	Capture all
(abc|def)	Matches abc or def

1

Экранирование

\.	Period (Dot)
\?	Вопросительный знак
\\      Слеш
\(      Скобка

1

1

Тренировка

2

Lodash

Array

2

Составные части

Object

Collection

Lang

Math

String

Util

Function

2

А зачем он нужен?

var q = {a: 1, b: 2};
var z = {a: 3};
// => {a: 3, b: 2}
var q = {a: 1, b: 2}
Object.assing(q, {a: 3});
// => {a: 3, b: 2}
var q = {a: 1, b: 2}
_.assign(q, {a: 3});
// => {a: 3, b: 2}

2

А зачем он нужен?

const q = {
	a: 1, 
	b: 2,
	...q,
}

2

А зачем он нужен 2?

const config1 = {
	db: {
		url: 'publicdb.mgbeta.ru',
		port: 27000,
	}
}

const config2 = {
	db: {
		user: 'public',
		password: 'public',
	}
}

const config = {
	db: {
		url: config1.url,
		port: config1.port,
		user: config2.user,
		password: config2.password,
	}
	... // ?
}

2

А зачем он нужен 2?

const config1 = {
	db: {
		url: 'publicdb.mgbeta.ru',
		port: 27000,
	}
}

const config2 = {
	db: {
		user: 'public',
		password: 'public',
	}
}

2

А зачем он нужен 2?

const config = {
	db: {
		url: config1.url,
		port: config1.port,
		user: config2.user,
		password: config2.password,
	}
	... // ?
}

2

А зачем он нужен 2?


const config = {
	...config1,
	...config2,
	db: {
		...config1.db,
		...config2.db,
	}
}

2

А зачем он нужен 2?

const config = {};
_.merge(config, config1, config2);

2

Array chunk

_.chunk(['a', 'b', 'c', 'd', 'e', 'f'], 2);
// => [['a', 'b'], ['c', 'd'], ['e', 'f']]

2

flatten, flattenDeep

 _.flatten([ [1,2], [3, 4], [5, 6] ]);
// => [1, 2, 3, 4, 5, 6]

 _.flatten([1, [2, [3, [4]], 5]]);
// => [1, 2, [3, [4]], 5]

_.flattenDeep([1, [2, [3, [4]], 5]]);
// => [1, 2, 3, 4, 5]

2

pairs

let o = {};
array.forEach(([key, val]) => {o[key] = val});

_.fromPairs([['a', 1], ['b', 2]]);
// => { 'a': 1, 'b': 2 }

_.toPairs(o);
// => [['a', 1], ['b', 2]]

2

Sets*

_.intersection([2, 1], [2, 3]);
// => [2]

_.union([2], [1, 2]);
// => [2, 1]

_.difference([2, 1], [2, 3]);
// => [1]

2

zip, unzip

var zipped = _.zip(
  ['a', 'b'], 
  [1, 2], 
  [true, false]
);
// => [['a', 1, true], ['b', 2, false]]
 
_.unzip(zipped);
// => [['a', 'b'], [1, 2], [true, false]]

2

zip, unzip

_.every
_.some
_.filter
_.map
_.mapValues
_.reject

2

forEach

_.forEach([1, 2], (val, key) => { console.log(key, val) })
_.forEach({a: 1, b: 2}, (val, key) => { console.log(key, val) })

_.map([1, 2], (u) => u * u)
_.map({a: 1, b: 2}, (u) => u * u) }

2

countBy


_.countBy([6.1, 4.2, 6.3], Math.floor);
// => { '4': 1, '6': 2 }
 
// The `_.property` iteratee shorthand.
_.countBy(['one', 'two', 'three'], 'length');
// => { '3': 2, '5': 1 }

2

groupBy

_.groupBy([6.1, 4.2, 6.3], Math.floor);
// => { '4': [4.2], '6': [6.1, 6.3] }
 
// The `_.property` iteratee shorthand.
_.groupBy(['one', 'two', 'three'], 'length');
// => { '3': ['one', 'two'], '5': ['three'] }

2

groupBy

var users = [
  { 'user': 'barney', 'age': 16, 'active': true },
  { 'user': 'fred',   'age': 40, 'active': false }
];



_.groupBy(users, u => u.age < 16 ? 'young' : 'old');

2

every, some

_.every([true, 1, null, 'yes'], Boolean);
// => false

_.some([true, 1, null, 'yes'], Boolean);
// => true

2

filter, find

var users = [
  { 'user': 'barney', 'age': 36, 'active': true },
  { 'user': 'fred',   'age': 40, 'active': false }
];

_.filter(users, { 'age': 36, 'active': true });
// => [{ 'user': 'barney', 'age': 36, 'active': true }]

_.find(users, { 'age': 36, 'active': true });
// => { 'user': 'barney', 'age': 36, 'active': true }

2

keyBy

var usersArray = [
  { 'user': 'barney', 'age': 36, 'active': true },
  { 'user': 'fred',   'age': 40, 'active': false }
];
 
const users = _.keyBy(usersArray, 'user');

console.log(users['fred'])

{
  'barney': { 'user': 'barney', 'age': 36, 'active': true },
  'fred': { 'user': 'fred',   'age': 40, 'active': false }
};

2

mapValues


var users = {
  'fred':    { ..., 'age': 40 },
  'pebbles': { ..., 'age': 1 }
};
 
_.mapValues(users, function(o) { return o.age; });
// => { 'fred': 40, 'pebbles': 1 } 
// (iteration order is not guaranteed)

2

sortBy

var users = [
  { 'user': 'fred',   'age': 48 },
  { 'user': 'barney', 'age': 36 },
  { 'user': 'fred',   'age': 40 },
  { 'user': 'barney', 'age': 34 }
];
 
_.sortBy(users, [function(o) { return o.user; }]);
// => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
 
_.sortBy(users, ['user', 'age']);
// => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]

2

RANDOM


_.random(0, 5);
// => an integer between 0 and 5
 
_.random(5);
// => also an integer between 0 and 5
 
_.random(5, true);
// => a floating-point number between 0 and 5
 
_.random(1.2, 5.2);
// => a floating-point number between 1.2 and 5.2

2

RANDOM

var array = [1, 2, 3, 4];

array[Math.floor(Math.rand() * array.length)];




_.sample([1, 2, 3, 4]);
// => 2

_.sampleSize([1, 2, 3], 2);
// => [3, 1]
 
_.sampleSize([1, 2, 3], 4);
// => [2, 3, 1]


_.shuffle([1, 2, 3, 4]);
// => [4, 1, 3, 2]

2

Merge

_.assign({}, {a:{a:'a'}}, {a:{b:'bb'}}) 
// => { "a": { "b": "bb" }}

_.merge({}, {a:{a:'a'}}, {a:{b:'bb'}}) 
// => { "a": { "a": "a","b":"bb" }}

_.defaults({}, {a:{a:'a'}}, {a:{b:'bb'}}) 
// => { "a": { "a": "a" }}

_.defaultsDeep({}, {a:{a:'a'}}, {a:{b:'bb'}}) 
// => { "a": { "a": "a", "b": "bb" }}

2

a && b && c || null


var object = { 'a': [{ 'b': { 'c': 3 } }] };

console.log(object.a[0].b.c);

if ( object && object.a && 
     object.a[0] && object.a[0].b
) {
	console.log(object.a[0].b.c);	
}

<span>
  {object && object.a && 
       object.a[0] && object.a[0].b && 
       object.a[0].b.c || 55}
</span>


_.get(object, 'a[0].b.c', 55);

2

get

const users = [...]
_.get(users, '[44].age')


_.get(users, 'length')

2

result

var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
 
_.result(object, 'a[0].b.c1');
// => 3
 
_.result(object, 'a[0].b.c2');
// => 4
 
_.result(object, 'a[0].b.c3', 'default');
// => 'default'
 
_.result(object, 'a[0].b.c3', _.constant('default'));
// => 'default'

_.result(users, 'length')

_.set(object, 'a[0].b.c', 123123);
_.unset(object, 'a[0].b.c');

_.update(object, path, updater)

2

Chain

var users = [
  { 'user': 'barney',  'age': 36 },
  { 'user': 'fred',    'age': 40 },
  { 'user': 'pebbles', 'age': 1 }
];
 
var youngest = _.head(_.map(_.sortBy(users), function(o) {
    return o.user + ' is ' + o.age;
  }))
// => 'pebbles is 1'

2

Chain

var users = [
  { 'user': 'barney',  'age': 36 },
  { 'user': 'fred',    'age': 40 },
  { 'user': 'pebbles', 'age': 1 }
];
 
var youngest = _
  .chain(users)
  .sortBy('age')
  .map(function(o) {
    return o.user + ' is ' + o.age;
  })
  .head()
  .value();
// => 'pebbles is 1'

2

once


var initialize = _.once(createApplication);
initialize();
initialize();
// => `createApplication` is invoked once

2

memoize

var object = { 'a': 1, 'b': 2 };
var other = { 'c': 3, 'd': 4 };
 
var values = _.memoize(_.values);
values(object);
// => [1, 2]
 
values(other);
// => [3, 4]
 
object.a = 2;
values(object);
// => [1, 2]

2

throttle, debounce

jQuery(window).on(
  'scroll', 
  _.throttle(updatePosition, 100)
);

3

JS

keys values

function f(x, y = 12) {
  // y is 12 if not passed (or passed as undefined)
  return x + y;
}
f(3) == 15


function f2(x, y = { a: { b: { c : 4 } } } ) {


}


const defaultParams = { 
  a: { 
    b: { 
      c : 4 
    } 
  } 
};

function f3(x, y = defaultParams ) {
}

3

keys values


function f4(x, ...y) {
  return x * _.sum(y);
}
f4(10, 1, 2, 3) == 60

3

keys values



function f4(name, height, width, length, weight) {
  
}
f4('test', 1, 1, 1, 30);
f4('test', null, null, null, 30);


function f5(props) {
  const {name, height, width, length, weight} = props;
}
f5({
  name: 'test', 
  weight: 30
});

3

keys values

class Some {
  field = 'default';
  constructor(props) {
    Object.assign(this, props);
  }
}

const some = new Some({field: 'other'})



class Some {
  field = 'default';
  constructor(props) {
    this.set(props);
    ...
  }
  set(props) {
    Object.assign(this, props);
  }
}
const some = new Some({field: 'other'})

3

keys values

Object.keys({
	a: 'hello',
	b: 'world'
}) 
// => ['a', 'b']


Object.values({
	a: 'hello',
	b: 'world'
}) 
// => ['hello', 'world']

3

reduce

const res = {
  age: _.max(users.map(u => u.age)),
  money: _.sum(users.map(u => u.money)),
}

const mapper = (sum, user) => {
  return {
    money: sum.money + user.money,
    age: Math.max(sum.age, user.age),
  }
}
users.reduce(mapper, {age: 0, money: 0})

3

async await

async function isUserTooYoung(id) {
    try {
        const a = await openDatabase(db)
        const b = await getCollection(a)
        const user = await find(b, {'id': id})
        return user.age < cutoffAge;
    } catch (err) {
        showError(err)
    }
}

3

async await

async useMiddlewares() {
    await this.beforeUseMiddlewares();
    const middlewares = _.flattenDeep(this.getUsingMiddlewares());
    middlewares.forEach((middleware) => {
      middleware && 
      typeof middleware === 'function' && 
      this.app.use(middleware);
    });
    return this.app
  }

3

async await

  async run(...args) {
    this.log.trace('CoreApp.run');
    this.config.db && await this.runDb();
    await super.run(...args);
    this.config.sockets && await this.runSockets();
    await this.afterRun();
  }

3

async await

  async getMiddlewares(...args) {
    return  [
     super.getMiddlewares(...args),
     ...require('./middlewares')(args),
    ]
    
  }
  async getModels(...args) {
    return  {
     super.getModels(...args),
     SomeModel: class ...,
     ...models,
    }
    
  }

3

3

Starter-kit

3

Задачи

1.   Проект 1 = 11 марта

2.   Задачи к урокам

Игорь Суворов

Thanks!

any questions?

программист-предприниматель

JavaScript

By Igor Suvorov

JavaScript

* template

  • 938