JavaScript関数のプロパティとメソッド、ES6の拡張機能の概要(アロー関数とrestパラメータ)

序論

JavaScriptにおける関数はオブジェクトであるため、独自のプロパティやメソッドを持っています。これらを理解することで、より効果的に関数を利用できます。

// 関数のさまざまな形式
function foo() {}
function foo(a) {}
function foo(a = 1) { return a }
function foo([a,b]) { return a + b }
function foo(a,...args) {return a}
var foo = function() {};
var foo = function f() {};
() => {}

プロパティとメソッド

nameとlengthプロパティ

// nameは関数名を返します
foo.name //foo
var f = function foo() {} //foo

// lengthは関数の引数の数を示します
// デフォルト値を持つ引数がある場合、lengthは正確ではありません
// 最初の引数がデフォルト値を持つ場合、それ以降の引数はカウントされません
function foo1(a,b) {}
foo1.length // 2
function foo2(a,b=1) {}
foo2.length // 1
function foo3(a=1,b,c) {}
foo3.length // 0

toString()

引数

argumentsオブジェクト

argumentsは関数の引数を保持する類似配列オブジェクトであり、関数の引数を取得または変更できます。これは関数に渡された引数を示し、関数定義時の引数とは異なります。厳格モードではこのオブジェクトを変更することはできません。

function foo(a) {
  arguments[0] = 1;
  return a;
}

foo(5) // 1
foo(2,3,5) // arguments.length == 3

デフォルト引数の指定

関数の引数にはデフォルト値を設定できます。

function foo(a = 1, b = 2) {}

// デフォルト値は式でも可能です
// 式は遅延評価されるため、実際に使われるまで計算されません
let x = 2;
function foo(a = x + 1) { return a }
foo() // 3
x = 4
foo() // 5

引数の構造化代入

restパラメータ

関数の引数の数が不定な場合は、...変数名を使用してrestパラメータを定義できます。

function foo(...args) { return args }
foo(1,23,4) // [1,23,4]

// 他のパラメータと組み合わせて使用可能
function foo(a,...args) {}

// restパラメータを使わずに同等の処理を行う
function foo() {
  return [].slice.call(arguments).sort();
}

注意: restパラメータは最後のパラメータのみが利用可能で、それ以外の位置ではエラーになります。

アロー関数

アロー関数により、関数をより簡潔かつ美しく記述できますが、いくつかの注意点があります。

// 引数がない場合は括弧が必要です
() => {}

// 一つの引数の場合は括弧を省略できます
a => { return a }

// 単一行のステートメントであれば波括弧とreturnを省略できます
a => a
// 波括弧を含む場合は明示的にreturnが必要です。さもないとundefinedが返されます
// 波括弧はコードブロックとして解釈されるため、関数内のreturnが無視されます
a => { return a }
a => { a } // undefined
a => { id:1, age:12 } // SyntaxErrorが発生
a => ({ id:1, age:12 }) //{ id:1, age:12 }
a => { return { id:1, age:12 } } //{ id:1, age:12 }
// returnしない場合はvoidを使用できます
a => void doesNotReturn()

注意事項:

  1. アロー関数のthisは定義された場所のオブジェクトを指します。実行場所ではなく、thisの固定化はアロー関数自身がthisを束縛する仕組みではなく、アロー関数がthisを持たないためです。このため、コンストラクタ関数としては使用できません。
  2. アロー関数はargumentsオブジェクトを持ちません。
  3. アロー関数はコンストラクタとして使用できません。したがって、new演算子による呼び出しはエラーになります。
  4. yield命令は使用できません。

末尾呼び出し最適化

関数呼び出し時には呼び出し履歴(コールフレーム)が作成されます。末尾呼び出しがある場合、現在の関数の前に末尾呼び出し関数のコールフレームが追加されます。関数がネストされており、すべてが末尾呼び出しである場合、連続したコールフレームが生成されます。末尾呼び出しは外部の状態に依存しないため、末尾呼び出し最適化によって内部のコールフレームのみが保持され、呼び出し時間とメモリの消費が削減されます。

function foo() {
  let a = 2;
  let b = 4;
  return g(a + b);
}
f();

// 以下のコードと同等
function f() {
  return g(6);
}
f();

// 以下のコードと同等
g(6);

タグ: javascript 関数 アロー関数 restパラメータ ES6

7月11日 22:46 投稿