< 戻る

関数のためのパーツ

関数を作成するためのパーツを、1つのグループとして以下に示す。

目次
  1. function
  2. return ステートメント
  3. this
  4. function*
  5. yield(yield*)
  6. async function
  7. await
  8. class(extends)

1. function

JavaScript の関数は、実際にはすべて Function オブジェクトです。これは、 (function(){}).constructor === Function というコードが true を返すことで確認することができます。

Funciton コンストラクターと関数宣言の違い。Function コンストラクターで生成された関数は、生成コンテキストにクロージャを作りません。つまり常にグローバルスコープで生成されます。これを実行すると、 Function コンストラクターの呼び出し元のスコープは入らず、自身のローカル変数とグローバル変数だけにアクセスできます。これは関数式のコードに eval を使うのとは異なります。

// Funciton コンストラクターと関数宣言の違い
var x = 10;

function createFunction1() {
    var x = 20;
    return new Function('return x;'); // この |x| はグローバルの |x| を表す
}

function createFunction2() {
    var x = 20;
    function f() {
        return x; // この |x| は上記のローカルの |x| を表す
    }
    return f;
}

var f1 = createFunction1();
console.log(f1());          // 10
var f2 = createFunction2();
console.log(f2());          // 20
function Car() {}
car1 = new Car();

Car.prototype.color = "A";
console.log(car1.color);

2. return ステートメント

return 文は、関数の実行を終了して、関数の呼び出し元に返す値を指定します。

function getRectArea(width, height) {
  if (width > 0 && height > 0) {
    return width * height;
  }
  return 0;
}

console.log(getRectArea(3, 4));
// expected output: 12

console.log(getRectArea(-3, 4));
// expected output: 0
function getRectArea(width, height) {
  if (width > 0 && height > 0) {
    return width * height;
  }
  return 0;
}

console.log(getRectArea(3, 4));
// expected output: 12

console.log(getRectArea(-3, 4));
// expected output: 0

3. this

関数の this キーワード は、JavaScript ではほかの言語と少々異なる動作をします。また、strict モードであるかどうかでも違いがあります。

ほとんどの場合、this の値はどのように関数が呼ばれたかによって決定されます (実行時結合)。これは実行時に代入によって設定することはできず、関数が呼び出されるたびに異なる可能性があります。ES5 では bind() メソッドが導入され、関数がどのように呼ばれたかに関係なく `this` の値を設定するすることができるようになり、ES2015 では、自身では this の結び付けを行わないアロー関数が導入されました (これは包含する構文上のコンテキストの this の値を保持します)。

const test = {
  prop: 42,
  func: function() {
    return this.prop;
  },
};

console.log(test.func());
// expected output: 42

4. function*

function* 宣言 (function キーワードにアスタリスクが付いたもの) は、 Generator オブジェクトを返すジェネレーター関数を定義します。

function* キーワードは、式の中でジェネレーター関数を定義するために使用することができます。

function* generator(i) {
  yield i;
  yield i + 10;
}

const gen = generator(10);

console.log(gen.next().value);
// expected output: 10

console.log(gen.next().value);
// expected output: 20
const foo = function*() {
  yield 'a';
  yield 'b';
  yield 'c';
};

let str = '';
for (const val of foo()) {
  str = str + val;
}

console.log(str);
// expected output: "abc"

5. yield(yield*)

yield キーワードは、ジェネレーター関数 (function* または古いジェネレーター関数) を一時停止したり再開したりするために使用します。

yield* 式は別のジェネレーターや反復可能なオブジェクトに委任するために使用されます。

function* foo(index) {
  while (index < 2) {
    yield index;
    index++;
  }
}

const iterator = foo(0);

console.log(iterator.next().value);
// expected output: 0

console.log(iterator.next().value);
// expected output: 1
function* func1() {
  yield 42;
}

function* func2() {
  yield* func1();
}

const iterator = func2();

console.log(iterator.next().value);
// expected output: 42

6. async function

非同期関数は async キーワードで宣言され、その中で await キーワードを使うことができます。 async および await キーワードを使用することで、プロミスベースの非同期の動作を、プロミスチェーンを明示的に構成する必要なく、よりすっきりとした方法で書くことができます。

非同期関数は式としても定義することができます。

async function キーワードは、式の中で async 関数を定義するために使用できます。

非同期関数は、 async function 文を使用して定義することもできます。

AsyncFunction コンストラクターは、新しい非同期関数オブジェクトを生成します。 JavaScript では、すべての非同期関数が実際に AsyncFunction オブジェクトです。

AsyncFunction はグローバルオブジェクトではないことに注意してください。これは以下のようなコードで取得することができます。

async function [name]([param1[, param2[, ..., paramN]]]) {
  statements
}

function resolveAfter2Seconds() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('resolved');
    }, 2000);
  });
}

async function asyncCall() {
  console.log('calling');
  const result = await resolveAfter2Seconds();
  console.log(result);
  // expected output: "resolved"
}

asyncCall();

7. await

await 演算子はプロミス (Promise) を待つために使用します。通常の JavaScript コードで、 async function の内部でのみ使用することができます。によって Promise が返されるのを待機するために使用します。

function resolveAfter2Seconds(x) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(x);
    }, 2000);
  });
}

async function f1() {
  var x = await resolveAfter2Seconds(10);
  console.log(x); // 10
}

f1();

8. class(extends)

クラス宣言は、プロトタイプベースの継承を使って、指定された名前の新しいクラスを作成します。

オブジェクト指向プログラミングでは、クラスはオブジェクトの特徴を定義します。クラスはオブジェクトのプロパティやメソッドのひな形定義であり、オブジェクトのより具体的なインスタンスが描かれる「青写真」です。

extends キーワードはクラス宣言やクラス式の中で、他のクラスの子であるクラスを生成するために使用します。

class Polygon {
  constructor(height, width) {
    this.area = height * width;
  }
}

console.log(new Polygon(4, 3).area);
// expected output: 12

////////////////////////////////////

const Rectangle = class {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
  area() {
    return this.height * this.width;
  }
};

console.log(new Rectangle(5, 8).area());
// expected output: 40

7. KnotTextでのECMAScriptの分類

参考:MDN Web DocsでのECMAScriptの分類

7-1. グローバルオブジェクトのプロパティ(JavaScriptの実行環境がWebブラウザーの場合)

7-1-1. グローバルオブジェクトの値プロパティ

7-1-2. グローバルオブジェクトの関数プロパティ

7-1-3. グローバルオブジェクトのコンストラクタープロパティ

コンストラクターとは、「オブジェクトを作成する能力を持たせた」関数で、「new」演算子によってオブジェクトインスタンスを作成することができる。

プリミティブデータ型のラッパーオブジェクト
真偽値window.Boolean()
文字列window.String()
数値window.Number()
window.BigInt()
シンボルwindow.Symbol()
オブジェクトのためのオブジェクト
window.Object()
関数のためのオブジェクト
window.Function()
関数のより高度なオブジェクトwindow.GeneratorFunction()
window.Generator()
window.AsyncFunction()
window.Promise()
配列のためのオブジェクト
window.Array()
配列のより高度なオブジェクトwindow.ArrayBuffer()
window.DataView()
window.SharedArrayBuffer()
型付き配列のためのオブジェクトwindow.Int8Array()window.Int16Array()
window.Uint8Array()window.Uint16Array()
window.Uint8ClampedArray()
window.Int32Array()window.BigInt64Array()
window.Uint32Array()window.BigUint64Array()
window.Float32Array()window.Float64Array()
日付・時刻のためのオブジェクト
window.Date()
正規表現のためのオブジェクト
window.RegExp()
エラーのためのオブジェクト
window.Error()window.EvalError()
AggregateError
InternalError
window.RangeError()
window.ReferenceError()
window.SyntaxError()
window.TypeError()
URIError
Keyed Collections 特殊なデータ集合
マップwindow.Map()window.WeakMap()
セットwindow.Set()window.WeakSet()
Managing Memory
window.WeakRef()
Reflection
window.Proxy()

7-1-4. グローバルオブジェクトのその他のプロパティ

Atomics
window.Atomics()
JSON
window.JSON()
Math
window.Math()
Reflect
window.Reflect()

7-2. ECMAScriptの演算子「計算・論理・代入」

7-2-1. ECMAScriptの演算子「計算」

7-2-2. ECMAScriptの演算子「論理」

7-2-3. ECMAScriptの演算子「代入」


7-3. ECMAScriptのステートメント

block ステートメントブロックを作る
if ステートメント(else)条件を作る
イテレーションステートメントdo-while ステートメント必ず1回は実行されるwhileステートメント
while ステートメント条件を満たすまで繰り返す
for ステートメント指定した回数まで繰り返す
for-in ステートメントオブジェクトのためのforステートメント
for-of ステートメント配列状のオブジェクト全般のためのforステートメント
for-await-of ステートメントPromiseオブジェクトのためのfor-ofステートメント
continue ステートメント繰り返しの処理をスキップして次の繰り返しへ進む
break ステートメント繰り返し・ラベル・switchステートメントの処理を中断してステートメントから抜け出す
switch ステートメント(case, default)条件に一致するcaseを実行する
throw ステートメント関数の中で例外を発生させ、catchが存在すればcatchに移行する。
try ステートメント(catch, finally)catchのためのfinallyでtryする?

7-4. オブジェクトのためのパーツ

instanceofオブジェクトが自身のプロトタイプにコンストラクタのprototype プロパティを持っているか判別する
newnew 演算子を使用すると、開発者はユーザー定義のオブジェクト型やコンストラクタ関数を持つ組み込みオブジェクト型のインスタンスを作成することができる
deleteオブジェクトからプロパティを削除する
in指定されたプロパティが指定されたオブジェクトにある場合にtrueを返す
superオブジェクトの親の関数を呼び出すために使用できる
プロパティアクセッサーオブジェクトのプロパティにアクセスする2種類の方法(ドット表記法、ブラケット表記法)
オブジェクトリテラルObject initializerによって作成するオブジェクト

7-5. 配列のためのパーツ

配列リテラル[a, b] = [1, 2] 代入 = [] 配列をつくる 配列リテラル 「配列」オブジェクト 配列初期化 Array()でも可

7-6. 関数のためのパーツ

functionキーワード いわゆるexpression 関数を作成する
return ステートメント
this[関数] キーワード
function*[ジェネレータオブジェクトを返す、ジェネレータ関数を定義]
yield(yield*)ジェネレータ関数 キーワード
async function キーワード 非同期関数
await Promiseオブジェクト 非同期関数内のみ
class(extends) いわゆるexpression ECMAScript 2015~のclass定義

7-7. その他のパーツ

use strictモード
,(comma) 演算子それぞれの演算対象を(左から右に)評価し、最後のオペランドの値を返します。これにより、複数の式が評価される複合式を作成することができ、複合式の最終値はそのメンバー式の一番右端の値となります。これは、for ループに複数の引数を提供する場合によく使用されます。
typeof 演算子対象の値のデータ型を返す
void 演算子必ずundefinedを返す
?.(Optional chaining) 演算子接続されたオブジェクトチェーンの深くに位置するプロパティの値を、チェーン内の各参照が正しいかどうかを明示的に確認せずに読み込むことを可能にします。
labeled ステートメントラベル付け?
import
export