高階関数・クロージャ・ジェネレータ・カリー化と関数の部分適用

高階関数

// 引数に関数をとる
arr = [1, 2, 3]
arr.map(n => n * 2);

// 戻り値として関数を返す
const hof = (ex, fn) => {
  retrun n => fn(n + ex);
};

const plusOneDouble = hof(1, n => n * 2);
console.log(plusOneDouble(4));
// (4 + 1) * 2 = 10

// returnを省略して書くと
const hof = (ex, fn) => n => fn(n + ex);

クロージャ

const counterMaker = (initialCount) => {
  let c = initialCount;
  const increment = () => c++;

  return increment;
};

const count = countMaker(1);
console.log(count(), count(), count());
// 1 2 3

countMakerの環境の中で実行されているから変数cの値が毎回リセットされることなく蓄積されていく。

ちなみにクロージャは必ずしも関数を返す必要はない。 あくまでクロージャとは、単に親関数スコープの変数を参照する関数のこと。

ジェネレータ

値を保持しつつ繰り返し処理や逐次処理を行うための手段。

function* rangeGenerator(end, start = 0) {
  let n = 0;

  for (let i = start; i < end; i++) {
    n += 1;
    yield i;
  }
}

const gen = rangeGenerator(3);
console.log(gen.next());    // { value: 0, done: false }
console.log(gen.next());    // { value: 1, done: false }
console.log(gen.next());    // { value: 2, done: false }
console.log(gen.next());    // { value: undefined, done: true }

これは??? 使いどころがちょっとわからない!

カリー化と関数の部分適用

ネストした関数。

const multi = (n, m) => n + m;
console.log(multi(2, 4));    // 8

const curriedMulti = n => {
  return m => n * m;
}

console.log(curriedMulti(2)(4);    // 8

const simpleCurriedMulti = n => m => n * m;
console.log(simpleCurriedMulti(2)(4));    // 8

ひとつめの関数は今まで見てきたものと同じ。 ふたつめは、nを引数に取り、mを引数にとってnとmの積を返す関数。 関数がネストしているので、引数を渡すかっこがふたつ必要になる。 みっつめは単にreturnを省略したもの。

カリー化された関数の一部の引数を固定して新しい関数をつくることができる。 「関数の部分適用」という。

const multi = n=> m => n * m;

const triple = multi(3);
console.log(triple(5));    // 15

ちょっと関数型プログラミングと仲良くなれたような気持ち!

便利な配列やオブジェクトのリテラル・非同期処理・コレクションの反復処理・関数型プログラミングの概要

朝活が成功するとブログ更新ができるぞ!として、モチベーションを維持。

便利な配列やオブジェクトのリテラル

// 分割代入
const [n, m] = [1, 4];

// スプレッド構文
const arr1 = [ 'A', 'B', 'C' ];
const arr2 = [...arr1, 'D', 'E' ];
// [ 'A', 'B', 'C', 'D', 'E' ]

const obj1 = { a: 1, b: 2, c: 3 };
const obj2 = {...obj1, d: 4, e: 5 };
// { a: 1, b: 2, c: 3, d: 4, e: 5 }

// プロパティ名のショートハンド
const foo = 65536;
const obj = { foo, bar: 4096 };
// { foo: 65536, bar: 4096 }

非同期処理

ES6 から導入された Promise 構文だと↓

const sleep = ms => new Promise(resolve => setTimeout(resolve, mis));

const greet = () => {
  consoloe.log('おやすみ')

  sleep(2000)
    .then(() => {
        // 2000sec たったあとの処理
    })
    .catch(err => {
      // エラー処理
    })
}

greet();

sleep() 関数が Promise クラスオブジェクトを返して、 then() のメソッドチェーンでつなぐ。then() は複数つなぐこともできる。 finally で例外のあるなしにかかわらず最後にかならず実行。

ES2017から導入された async/awasit という構文だと↓

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));

const greet = async() => {
  console.log('おやすみ');

  try {
    await sleep(2000);
    // 処理
  } catch (err) {
    // エラー処理
  }
}

greet();

async で定義した Async 関数は、本文中に await を前置きすることで、他の Async 関数の実行結果を待つようになる。 Async 関数は暗黙のうちに Promise オブジェクトを返している。

コレクションの反復処理

関数型プログラミングについては経験がない。。 入力に対して同じ作用と同じ出力が保証されていること、が関数型プログラミングの良さ。これを参照透過性という。

const arr = [ 1, 2, 3, 4, 5, 6, 7, 8];

arr.map(n => n * 2);
arr.filter(n => n % 3 === 0);
arr.find(n => n > 4);

arr.every(n => n != 0);
// すべての要素が条件を満たすかを真偽値で返す

arr.some(n => n > 8);
// 条件を満たす要素がひとつでもあるかを真偽値で返す

arr.includes(5);
// 指定した要素が含まれるかを真偽値で返す

arr.reduce((n, m) => n + m);
// 配列の要素を、与えた式で畳み込んだ値を返す

arr.sort((n, m) => n > m ? -1 : 1);
// 与えられた比較関数(戻り値が -1: 前に移動、0: 移動しない、1: 後ろ
  に移動)によって並べ替えた新しい配列を返す

元の配列をいっさいいじらずに、新しい配列を生成して返す。

関数型プログラミングの概要

const arr = [ 1, 2, 3, 4, 5, 6, 7, 8];

const double = n => n * 2;
arr.map(double)
// arr.map(n => n * 2); と同じ結果
  • 無名関数
  • 変数に関数を代入できる(つまり、無名関数に名前をつけることができる)
  • 高階関数(関数の引数に関数を渡したり、戻り値として関数を返す)
  • 部分適用(関数に特定の引数を固定した新しい関数をつくる)
  • 複数の高階関数を合成してひとつの関数にできる

:thinking:

クラス構文

夜に活動があったり(Ikejiri.rbオンライン読書会)、夜中にムスメ対応が発生すると、睡眠時間がずれてしまう。。 仕方なし、そういうときは受け入れて、またできるときに、やる。

クラス構文

constructor は継承されないので、継承先で constructor() と明示的に書く必要がある。

class Parent {
  constructor(name) {
    this.name = name;
  }

  greet() {
    console.log(`わたしは${this.name}です`);
  }

  static explain(name) {
    console.log(`${name}には子どもがいます`);
  }
}

class Child extends Parent {
  constructor(name) {
    super(name);
  }

  cry() {
    console.log(`${this.name}が泣きました`);
  }
}

const person1 = new Parent('かとりえ');
person1.greet();          // わたしはかとりえです
Parent.explain('もじゃ');          // もじゃには子どもがいます
const person2 = new Child('ムスメ');
person2.cry();          // ムスメが泣きました

なるほど? いまいちまだ this がよくわからない。。

package.jsonのscripts・ECMA Script2015

週末をはさむと少し「ひさしぶり感」がある。 花粉症がやばくなってきたので病院に行く必要がある。。

package.jsonのscripts

npmコマンド、それはつまりyarnコマンド。 package.jsonscripts にエントリを記述しておくと、あたかもnpmコマンドとして実行できる。

たとえば下記のように記述してある場合(本文より引用)

"scripts": {
  "start": "react-scripts start", 
  "build": "react-scripts build", 
  "test": "react-scripts test", 
  "eject": "react-scripts eject"
},

npm start (yarn start) を実行すると、 ./node_modules/.bin/react-scripts start がはしる。 ということでここを便利につかうと便利。 のちほどまた出てくるようなので期待。

ECMA Script2015

さていよいよ、の前に JavaScript の基本的なおさらいから。ほとんど書いたことない私にはありがたい。

varは使わない

再代入の必要がない場合は const を、どうしても再代入の 必要がある場合だけ let を使い、var は使わない!!

function での関数宣言とアロー関数式での宣言 は this の挙動が変わる

funciton による関数宣言では、その文脈における直上のオブジェクトが this になる。 直上に定義 したオブジェクトがない場合はグローバルオブジェクトね。 いっぽう、アロー関数式では this はその関数それ自体になる。

const obj1 = { 
  num: 444,
  fn: function() { 
    console.log(this.num);
  } 
};

const obj2 = { 
  num: 888,
  fn:()=>{ 
    console.log(this.num);
  } 
};

obj1.fn(); // 444 
obj2.fn(); // undefined

関数のデフォルト引数

constplusOne=(n=0)=>n+1;

console.log(plusOne(5)); // 6 
console.log(plusOne()); // 1

VSCodeのプラグインをインストール・package-lock.jsonのあつかい

VSCodeプラグインをインストール

本の中でおすすめされているVSCodeプラグインをインストールしたり内容を確認してみたり

サンプルコードをチェックアウトすると、 .vscode/extentions.json というファイルがあって、そのなかに同じプラグインが書かれています。 なので、サンプルコードをVSCodeで開くと、VSCodeがこれらをダウンロードするかどうか聞いてきます!便利!! (右下にメッセージが出てきました)

同じ .vscode ディレクトリには settings.json がいて、本の中でもおすすめしていますがチームで共通で使用したい設定などが書かれています。 これは LiveShare モードでペアプロ・モブプロするときにあると便利だそう。

気になったプラグインを2つ、スクショでご紹介。

indent-rainbow(oderwat.indent-rainbow)

f:id:katoriexxxkatorie:20200213054446p:plain
インデントが虹色〜(そのまま

vscode-icons(vscode-icons-team.vscode-icons)

f:id:katoriexxxkatorie:20200213054521p:plain
アイコンがかわいい〜

気に入ったので社用PCでも同じ設定してみよう。

package-lock.jsonのあつかい

このサンプルコードには package-lock.json はコミットされていない。 今まで業務で package-lock.json もコミットされていたことばかりだったのと、 Gemfile.lock もコミットするイメージだったので、ちょっと疑問に。

かるくググった感じでも、 package-lock.json は必要、という意見もみられる。

こちらはnpmの公式↓(まだ読んでない)

npm-package-lock.json | npm Documentation

npmの特定のバージョンをインストールする・サンプルコードで動かしてみる・VSCodeのプラグインをインストール

昨日は大江戸Ruby会議08が開催されて、行けなかった私は起きてからしばらく楽しそうなTLをながめていました。

今朝も「りあクト!」の続きから!

npmの特定のバージョンをインストールする

npmのバージョンが合っていなかったので、npm i -g npm@6.8.0 でインストールしたところ、無事入りました。

しかしその後の npx create-react-app hello-world --typescript でこける。

>> npx create-react-app hello-world --typescript
npx: 99個のパッケージを6.358秒でインストールしました。

Creating a new React app in /Users/katorie/js_ex/hello-world.

The --typescript option has been deprecated and will be removed in a future release.
In future, please use --template typescript.

Installing packages. This might take a couple of minutes.
Installing react, react-dom, and react-scripts with cra-template-typescript...

yarn add v1.16.0
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
error @typescript-eslint/eslint-plugin@2.18.0: The engine "node" is incompatible with this module. Expected version "^8.10.0 || ^10.13.0 || >=11.10.1". Got "10.9.0"
error Found incompatible module.
info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command.

Aborting installation.
  yarnpkg add --exact react react-dom react-scripts cra-template-typescript --cwd /Users/katorie/js_ex/hello-world has failed.

Deleting generated file... package.json
Deleting generated file... yarn.lock
Deleting hello-world/ from /Users/katorie/js_ex
Done.

🍊😔

サンプルコードで動かしてみる

https://github.com/oukayuka/ReactBeginnersBook-2.0/tree/master/01-hello/02-hello

サンプルコードを clone して、02-hello ディレクトリで npm i してから npm start すると…

f:id:katoriexxxkatorie:20200212055318p:plain
でた!

VSCodeプラグインをインストール

本の中でおすすめされているプラグインを、ひとまず盲目的にインストール。

  • Prettier(esbenp.prettier-vscode)
  • ESLint(dbaeumer.vscode-eslint)
  • stylelint-plus(hex-ci.stylelint-plus)
  • Visual Studio IntelliCode(VisualStudioExptTeam.vscodeintellicode)
  • Bracket Pair Colorizer(coenraads.bracket-pair-colorizer)
  • indent-rainbow(oderwat.indent-rainbow)
  • vscode-icons(vscode-icons-team.vscode-icons)
  • Debugger for Chrome(msjsdiag.debugger-for-chrome)
  • VSCodeVim(vscodevim.vim)
  • Live Share(ms-vsliveshare.vsliveshare)

明日はこのプラグインたちを確認するところから。

朝活をはじめてみる・React環境構築

朝活をはじめてみる

きっかけがあって、朝5時から 朝活 をはじめてみました。

いつも夜22時前くらいに娘を寝かしつけて、そのときに一緒に寝てしまい午前2時くらいに起きてすこし活動していることが多かったのですが、

そのまま朝まで寝てしまって、5時から起きて活動する、という生活にシフトしようと思います。

夜中の活動は、

  • 寒くて体調を崩すリスクがある
  • ノってくるとそのまま眠れなくなる

という問題があります。

きっかけは TECH PLAY女子部でやっている方がいたので便乗です。

 

React環境構築

今日はReactをはじめるところから。

購入してあった「りあクト!」に沿ってすすめます。

フロントエンド開発がほぼ経験なしであることを話したら、同僚がおすすめしてくれた本です。

 

まえがき・プロローグを読んでだいたいの状況を把握。

本部宇宙で使用しているソフトウェアは以下の通り。

 

  • React
  • Create React App
  • TypeScript
  • React Router
  • react-router-dom
  • Redux
  • React Redux
  • Redux-Saga

 

それでは環境構築をはじます。

nodenvはanyenvでいれることにしました。

GitHub - anyenv/anyenv: All in one for **env

  

メモ

npmのバージョンが本(6.8.0)よりあがっている状態。