関数(アロー関数, 引数のデフォルト, 可変長引数, スコープ)

関数の基本的な記述方法について解説します。「アロー関数」「引数のデフォルト」「可変長引数」「スコープ」について取り上げています。

定義方法|ES2015より前

// function命令
function aaa(x, y) {
    return x + y
}

// 関数リテラル
var aaa= function(x, y) {
    return x + y
}
 
// Functionコンストラクタ
// グローバル変数を参照するため、意図しない動作が起こる可能性があるので非推奨です。
var aaa = new Function('x', 'y', 'return x + y')

定義する位置に注意

funtion命令で定義された関数

同一scriptタグ内であればどこからでも呼べます。異なるscriptタグの場合、関数呼出しのscriptタグよりも、関数定義のscriptタグを先に記述しないといけません。

関数リテラルで定義された関数

同一scriptタグ内であっても、呼び出しもとより前に定義しないとエラーになります。

定義方法|ES2015以降
( アロー関数 )

ES2015以降、関数リテラルをアロー関数で書きやすくできます。

var aaa = (x, y) => {
    return x + y
}

引数が一つであれば () を省略できます。

var aaa = x => {
    return x + 2
}

さらに、一文であれば、{}return も省略できます。

var aaa = x => x + 2

thisのスコープ

アロー関数を利用すると this のスコープは周囲と同じになるため、退避させる必要がなくなります。

// 退避させる必要あり
var counter = {
  count: 0,
  start: function() {
    var self = this
    setTimeout(function() {
      console.log(self.count++)
    }, 1000)
  }
}
 
// 退避させなくても良い
var counter = {
  count: 0,
  start: function() {
    setTimeout(() => {
      console.log(this.count++)
    }, 1000)
  }
}

スコープチェーン

内側のスコープから順に変数を探していきます。この仕組みをスコープチェーンと言います。

下記例で具体的な動作を確認できます。

let name1 = 'aaa';
let name2 = 'aaa';
let name3 = 'aaa';
 
function bbb() {
  let name2 = 'bbb';
  let name3 = 'bbb'
  function ccc() {
    let name3 = 'ccc';
    console.log(name1); // aaa
    console.log(name2); // bbb
    console.log(name3); // ccc
  }
  ccc();
}
 
bbb();

引数

デフォルト値

const xxx = (url, method = 'GET') => console.log(method)
 
xxx('wakuwakubank.com')          // GET
xxx('wakuwakubank.com', 'POST')  // POST

可変長引数

addNumbers = (...numbers) => {
  console.log(numbers)  // [1, 2, 3, 4, 5, 6, 7]
 
  return numbers.reduce((sum, number) => {
    return sum + number
  })
}

console.log(addNumbers(1,2,3,4,5,6,7))  // 28