Yabu.log

ITなどの雑記

JavaScriptパターン第4章ノート

JavaScriptパターン ―優れたアプリケーションのための作法

JavaScriptパターン ―優れたアプリケーションのための作法

4章のテーマは関数です。

関数の記述方法

関数式

Var add = function add(a,b){
    return a + b;
};

Addを削除して無名関数にすることも可能。

関数宣言

function foo(){
    //処理内容
}

関数式と関数宣言の違いについて

  • 式は使用される前に記述されている必要がある、
  • 宣言は使用箇所の後に書いても問題ない(呼び出すことができる)
  • 宣言はグローバル空間か別の関数の中にしか存在できない。
  • 式で宣言したものは関数の引数で指定したり、戻り値として返すこともできる。
//- 式は使用される前に記述されている必要がある、
let num =  add(1,2)
Add = function(a,b){return a+ b};

//宣言は使用箇所の後に書いても問題ない(呼び出すことができる)
num = add2(1,2)
function add2(a,b){return a+b}

巻き上げ時の動作の違い

関数式は変数に代入しているので巻き上げが起こった場合エラーになってしまう 関数宣言の場合は新たに宣言した方で呼び出される

function test1(){
  console.log("test1");
}
function test2(){
  console.log("test2");
}

function hoisting(){
  console.log(typeof test1);//function
  console.log(typeof test2);//undefined
  test1();//hoisting test1
  test2();//Uncaught TypeError: test2 is not a function

  function test1(){
    console.log("hoisting test1");
  } 
  var test2 = function(){
    console.log("hoisting test2");
  }
  
}

ちなみに関数式の末尾にはセミコロンを必ずつけるべき(つけなくても補間されるけどね)

APIパターン

コールバック

関数を引数として別の関数に渡すことをコールバックという 渡すときには丸括弧()をつけない。(つけると呼び出した時点でも実行されちゃう…)

手頃なサンプルとしてArray.prototype.map()がある。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

var test = [1,2,3].map(function(a){
    return a *a;
});

//ES2015 allow function ver
var test = [1,2,3].map((a) =>{
    return a *a;
});

余談ですが、1年ほど前にpythonを勉強している時にmapとreduceというのは使いまくった覚えがあります。

またまた余談ですが、ネットを眺めると、関数は常に()付きで扱う、的な勘違いをして無駄に実行してしまうサンプルなどが散見される。qiitaなら優しい人がその丸カッコは不要ですよ〜って指摘してくれるけど

カリー化

Wikipediaの例はわかりやすかったが、本書の例は結構難しい。

本書の例

function schofinkelize(fn){
  var slice = Array.prototype.slice,
    stored_args = slice.call(arguments,1);
  return function(){
    var new_args = slice.call(arguments),
      args = stored_args.concat(new_args);
    return fn.apply(null,args);
  }
}

//nomal function
function add(x,y){
  return x + y;
}

// currying
var newadd = schofinkelize(add,5);
newadd(4);//9

Wikipedia

function div(x, y) { return x / y; }
//div(1, 3) == 1 / 3, これはカリー化ではない。

function cdiv(x) { return function(y) { return div(x, y); } }
console.log(cdiv(10)(3));
//=> 10/3 = 3.333...

var inv = cdiv(1);
console.log(inv(2));
//=> 1/2 = 0.5

引数の一部を部分的に適応した関数を新たに作る、程度の認識。 callbackを使うとこんなこともできるよ、という例で出したため今回はあまり掘り下げず、 Javascript関数型プログラミングを学ぶ素敵な本を見つけたのでそこでみっちりやる予定。