LoginSignup
0
0

More than 1 year has passed since last update.

【JavaScript】モジュール② ES Moduleと即時関数

Posted at

はじめに

Udemyの【JS】ガチで学びたい人のためのJavaScriptメカニズムの講座の振り返りです。

前回の記事

目的

  • モジュールについての理解を深める

本題

1. ES Moduleと即時関数

二つの動きがとても似ているのでコードで確認していく

例1

前提

即時関数を定義している状態

main.js
// moduleAという変数に対して、即時関数が定義されている
const moduleA = (function () {

  console.log('IIFE called');

  let privateVal = 1;
  let publicVal = 10;

  function publicFn() {
    console.log('publicFn called: ' + privateVal++);
  }

  function privateFn() {

  }
  // 戻り値を定義しているので、以下のオブジェクトがmoduleAに返る
  return {
    publicFn,
    publicVal
  }
})();

上記のmoduleAをpublicFnを通して読んでみる

main.js
const moduleA = (function () {

  console.log('IIFE called');

  let privateVal = 1;
  let publicVal = 10;

  function publicFn() {
    // privateValが1ずつカウントアップする仕組みがある
    console.log('publicFn called: ' + privateVal++);
  }

  function privateFn() {

  }

  return {
    publicFn,
    publicVal
  }

})();

  // 下記のようにするとpublicFnを実行できる
  // privateFn, privateValは外部から呼べない
  moduleA.publicFn();
  // 1ずつ増えていく
  moduleA.publicFn();
  moduleA.publicFn();
  // 下記のようにすると10という値が取れてくる
  console.log(moduleA.publicVal++)
  // こちらも++すると11,12とカウントアップする
  console.log(moduleA.publicVal++)
  console.log(moduleA.publicVal++)

例2

moduleAとpublicFnをmoduleBに格納する

main.js
const moduleA = (function () {

  console.log('IIFE called');

  let privateVal = 1;
  let publicVal = 10;

  function publicFn() {
    console.log('publicFn called: ' + privateVal++);
  }

  function privateFn() {

  }

  return {
    publicFn,
    publicVal
  }

})();

  // 以下のように即時関数を定義して格納する
  // 一般的には仮引数、実引数に値を入れて使用する
  const moduleB = (function(moduleA) {
    // 内部でmoduleAを使用
    moduleA.publicFn();
    moduleA.publicFn();
    moduleA.publicFn();
    console.log(moduleA.publicVal++)
    console.log(moduleA.publicVal++)
    console.log(moduleA.publicVal++)
  })(moduleA);

  // 省略して書くこともできる
  // moduleAはオブジェクトなので、直接publicFn, Valを分割代入可能
  const moduleB2 = (function( {publicFn, publicVal }) {
    // moduleAを使用していないのでmoduleAを削除
    publicFn();
    publicFn();
    publicFn();
    console.log(publicVal++)
    console.log(publicVal++)
    console.log(publicVal++)
  })(moduleA);

  // さらに名前をつけて書くことも可能

  const moduleB3 = (function( {publicFn: Fn, publicVal: Val }) {
    // このようにすると上記のmoduleB2と同じ結果が出力される
    Fn();
    Fn();
    Fn();
    console.log(Val++)
    console.log(Val++)
    console.log(Val++)
  })(moduleA);

例3

即時関数で書いていたものをES moduleに書き直す

moduleA.js
// moduleAの値をそのままコピー
  console.log('ES Module called');

  let privateVal = 1;
  // publicとあるものは外部に露出したいので(ファイルの外で使いたい)exportをつける
  // 渡す時にエラーが発生しないようにプリミティブ型でなくオブジェクトとして定義する
  export let publicVal = { prop : 10 };

  export function publicFn() {
    console.log('publicFn called: ' + privateVal++);
  }

  function privateFn() {

  }
moduleB.js
// // moduleBも全体をコピーして持ってくる
// const moduleB = (function(moduleA) {
  // 以下の書き方に変更
  import { publicFn as Fn, publicVal as Val} from "./moduleA.js";
  Fn();
  Fn();
  Fn();
  // moduleAに合わせて変更
  console.log(Val.prop++)
  console.log(Val.prop++)
  console.log(Val.prop++)

今日はここまで!

参考にさせて頂いた記事

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0