6時だョ!!全員集合!!

Rails・JavaScrictを中心にアウトプットします。

2021年12月23日 JavaScript (JS Primer) 関数とスコープ

クロージャーについての理解が曖昧だったのでJS primer以外の記事も読んでみました。

function User(){
    // private member
    let name = "Jason";

    // public member
    this.getName = function(){
        return name;
    };
}

let user01 = new User();

// 直接プライベートメンバにはアクセス出来ない
console.log(user01.name); // -> undefined

// パブリックメソッド経由でプライベートメンバにアクセスする
console.log(user01.getName()); // -> "Jason"
  • コード内のプライベートメンバ(ここではname)には、外側から参照できない」
  • 「コード内のプライベートメンバ(ここではname)を参照するには、パブリックメソッド(ここではgetName)を経由するしかない」

上記の2点が重要でクロージャーを理解するのに必要な知識でした。 JS primerでは関数に状態を持たせる手段としてで書かれていましたがクロージャーこの記事を読んで理解を深められたので引用しました。

  • getNameに代入されている関数は外側の変数nameを参照し続けています。
  • クロージャーとは静的スコープとメモリ管理の仕組みを利用して、関数内から特定の変数を参照し続けることで関数が状態を持てる仕組みのことを言います。

ここまで数日にあたりクロージャーと向き合ってきましたが、どの記事の記述にもあるように言葉で伝えるのは難しいという事です。しかし、理解してしまえばそこまで難しくはないので根気よく向き合うと良いかもしれません。

クロージャーの用途

  • 関数に状態を持たせる手段として
  • 外から参照できない変数を定義する手段として
  • グローバル変数を減らす手段として
  • 高階関数の一部分として

これまでまとめてきた中で高階関数に関してだけ記載してこなかったのでここでは高階関数のみをまとめていきます。

高階関数の一部分としてクロージャーを使う場合のコード例に100の値も追加して記述しました。こうして使い回しが効く関数にできるのもクロージャーの用途です。

function greaterThan(n) {
    return function(m) {
        return m > n;
    };
}
// 5より大きな値かを判定する関数を作成する
const greaterThan5 = greaterThan(5);
const greaterThan100 = greaterThan(100);
console.log(greaterThan100(101)); // => true
console.log(greaterThan5(4)); // => false
console.log(greaterThan5(5)); // => false
console.log(greaterThan5(6)); // => true
  • greaterThan()に引数を渡して実行した結果を変数に代入します。 nに引数に指定した数字が入ります。
  • console.log()を実行した際は引数がfunctionに渡って実行されています。

参考

クロージャー