1. JavaScriptのクラス構文とは?基本から応用まで
    1. クラスの基本的な概念とES6構文
    2. コンストラクタとメソッドの定義
    3. ゲッター・セッター、静的メソッドなどの応用
  2. 継承の仕組みを理解し、コードの再利用性を高めよう
    1. 継承の基本的な概念とextendsキーワード
    2. superキーワードと親クラスの呼び出し
    3. メソッドのオーバーライドと多態性
  3. JavaScriptクロージャの奥深さ:関数とスコープの関係
    1. クロージャの定義とレキシカルスコープ
    2. 状態の保持とプライベート変数
    3. クロージャの活用例(ファクトリ関数、カウンターなど)
  4. コールバック関数:非同期処理の基本をマスター
    1. コールバック関数の基本と役割
    2. 非同期処理におけるコールバックの利用
    3. 注意点とPromise/async-awaitへの発展
  5. JavaScriptの便利な小技集:コメント、文字列操作、数値計算
    1. コードの可読性を高めるコメントの書き方
    2. 文字列操作の便利なメソッド
    3. 数値計算のテクニックと注意点
  6. まとめ
  7. よくある質問
    1. Q: JavaScriptにおける「クラス」とは何ですか?
    2. Q: JavaScriptの「継承」とはどのような仕組みですか?
    3. Q: 「クロージャ」はJavaScriptでどのように使われますか?
    4. Q: コールバック関数はどのような場面で必要になりますか?
    5. Q: JavaScriptでコメントアウトや改行、文字列操作を行うにはどうすれば良いですか?

JavaScriptのクラス構文とは?基本から応用まで

JavaScriptにおけるクラスは、オブジェクト指向プログラミングの概念を、より直感的で馴染みやすい構文で実現するために、ES6(ECMAScript 2015)で導入されました。

それ以前のJavaScriptは「プロトタイプベース」のオブジェクト指向言語であり、クラスのような明確な「設計図」の概念は存在しませんでした。しかし、クラス構文の導入により、他の言語(JavaやC#など)に慣れている開発者にとっても、より理解しやすいオブジェクトの生成と管理が可能になっています。

クラスは、オブジェクトの「設計図」や「テンプレート」として機能し、その設計図に基づいて複数のインスタンス(個々のオブジェクト)を生成できます。これにより、共通のプロパティ(データ)とメソッド(関数)を持つオブジェクトを効率的に作成し、コードの構造化を促進します。

クラスの基本的な概念とES6構文

JavaScriptのクラスは、classキーワードを使って定義されます。この構文は、内部的には従来のプロトタイプベースの継承メカニズムを使用していますが、開発者にはより簡潔で分かりやすい記述を提供します。

例えば、Personというクラスを定義する場合、以下のように記述できます。

class Person {
  // コンストラクタ
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  // メソッド
  greet() {
    return `こんにちは、私の名前は${this.name}です。${this.age}歳です。`;
  }
}

// クラスからインスタンスを生成
const person1 = new Person('太郎', 30);
console.log(person1.greet()); // こんにちは、私の名前は太郎です。30歳です。

この例では、Personクラスがnameageというプロパティを持ち、greetというメソッドを持っています。このように、クラスを定義することで、同じ構造を持つオブジェクトを簡単に生成できるようになります。

参考情報: MDN Web Docs JavaScript ガイド – クラス

コンストラクタとメソッドの定義

クラスには、必ずしも必要ではありませんが、特別なメソッドとしてconstructor()を定義できます。これは、クラスから新しいインスタンスが作成される際に自動的に呼び出される初期化のためのメソッドです。

constructor()は、インスタンスが持つべき初期状態(プロパティ)を設定するのに使われます。上記のPersonクラスの例では、nameageという引数を受け取り、それらをthis.namethis.ageとしてインスタンスに割り当てています。thisキーワードは、現在のインスタンス自身を指します。

一方、メソッドはクラスのインスタンスが実行できる「動作」を定義します。例えば、greet()メソッドは、Personインスタンスが自分自身の名前と年齢を使って挨拶を生成する動作を定義しています。メソッドは、クラス内でシンプルに関数として定義され、インスタンスからドット記法(例: person1.greet())で呼び出すことができます。

これらのコンストラクタとメソッドを適切に定義することで、オブジェクトがどのようなデータを持つべきか、そしてどのような振る舞いをするべきかを明確に表現できます。

ゲッター・セッター、静的メソッドなどの応用

JavaScriptのクラスでは、基本的なプロパティとメソッドの他に、より高度な機能を実装するための構文も提供されています。

  • ゲッターとセッター(get/set:

    これらはプロパティへのアクセスを制御するための特別なメソッドです。ゲッター(get)はプロパティの値を取得する際に、セッター(set)はプロパティの値を設定する際に実行されます。これにより、プロパティの読み書きに追加のロジック(例:入力値の検証、フォーマット変換など)を組み込むことができます。例えば、年齢が負の数にならないようにセッターでチェックするといった使い方が可能です。

    class Product {
      constructor(price) {
        this._price = price; // _で内部プロパティを示す慣習
      }
      get price() {
        return this._price * 1.1; // 消費税込みの価格を返す
      }
      set price(newPrice) {
        if (newPrice < 0) {
          console.error("価格は負の数にできません。");
          return;
        }
        this._price = newPrice;
      }
    }
  • 静的メソッド(static:

    静的メソッドは、クラスのインスタンスではなく、クラス自体に直接関連付けられたメソッドです。staticキーワードを使って定義され、クラス名.メソッド名()のようにして呼び出します。これらは、特定のインスタンスの状態に依存しない、クラス全体に関わるユーティリティ関数やファクトリメソッドとしてよく利用されます。例えば、複数のPersonインスタンスを比較するようなメソッドは、静的メソッドとして定義すると便利です。

    class Calculator {
      static add(a, b) {
        return a + b;
      }
    }
    console.log(Calculator.add(5, 3)); // 8

これらの応用的な機能は、より堅牢で保守しやすいクラス設計を可能にし、コードの柔軟性を高めます。

継承の仕組みを理解し、コードの再利用性を高めよう

オブジェクト指向プログラミングの主要な柱の一つである「継承」は、既存のクラスの機能(プロパティやメソッド)を新しいクラスが引き継ぎ、それを拡張したり変更したりする仕組みです。

JavaScriptのクラス構文においても、この継承の概念はextendsキーワードによって簡潔に表現されます。継承を利用することで、共通する機能を親クラス(スーパークラス)にまとめ、子クラス(サブクラス)は親クラスの機能をそのまま利用したり、独自の機能を追加・上書きしたりすることができます。

これにより、コードの重複を減らし、システムの保守性や拡張性を大幅に向上させることが可能になります。例えば、一般的なAnimalクラスを定義し、そこからDogCatといったより具体的な動物のクラスを派生させるといった使い方が典型的です。

継承の基本的な概念とextendsキーワード

継承とは、あるクラス(親クラス、スーパークラス)が持つプロパティやメソッドを、別のクラス(子クラス、サブクラス)が受け継ぐメカニズムを指します。これにより、コードの再利用性が向上し、共通の機能を一度だけ定義すれば、複数の子クラスで利用できるようになります。

JavaScriptでは、extendsキーワードを使用して継承を表現します。例えば、Animalという親クラスがあり、そこからDogという子クラスを継承させる場合、以下のように記述します。

class Animal {
  constructor(name) {
    this.name = name;
  }
  speak() {
    return `${this.name}が何か言っています。`;
  }
}

class Dog extends Animal {
  bark() {
    return `${this.name}がワンワンと吠えています!`;
  }
}

const myDog = new Dog('ポチ');
console.log(myDog.speak()); // ポチが何か言っています。
console.log(myDog.bark());  // ポチがワンワンと吠えています!

DogクラスはAnimalクラスのspeak()メソッドを継承しているため、独自のメソッドを定義しなくてもspeak()を呼び出すことができます。これはコードの重複を避け、効率的な開発に繋がります。

参考情報: MDN Web Docs JavaScript ガイド – 継承

superキーワードと親クラスの呼び出し

子クラスが親クラスから継承する際、子クラスのコンストラクタ内ではsuper()という特別な関数を呼び出す必要があります。このsuper()は、親クラスのコンストラクタを実行し、親クラスで定義されている初期化処理(例えば、プロパティの初期化)を行います。

super()を呼び出す前にthisキーワードを使用しようとするとエラーが発生するため、子クラスのコンストラクタでは必ず最初にsuper()を呼び出すことが重要です。

class Vehicle {
  constructor(brand) {
    this.brand = brand;
  }
  getBrand() {
    return `ブランド: ${this.brand}`;
  }
}

class Car extends Vehicle {
  constructor(brand, model) {
    super(brand); // 親クラスのコンストラクタを呼び出す
    this.model = model;
  }
  getModel() {
    return `${this.getBrand()}, モデル: ${this.model}`;
  }
}

const myCar = new Car('トヨタ', 'プリウス');
console.log(myCar.getModel()); // ブランド: トヨタ, モデル: プリウス

また、子クラス内で親クラスのメソッドを呼び出したい場合にもsuperキーワードを使用します。これはsuper.メソッド名()の形式で記述し、親クラスのオリジナルの振る舞いを呼び出しつつ、子クラスで追加の処理を行いたい場合に役立ちます。

例えば、親クラスのspeakメソッドを呼び出した後に、子クラス固有のメッセージを追加するといったことができます。

メソッドのオーバーライドと多態性

継承において、子クラスが親クラスと同じ名前のメソッドを定義することを「オーバーライド」と呼びます。子クラスでメソッドをオーバーライドすると、その子クラスのインスタンスからそのメソッドが呼び出された際には、親クラスのメソッドではなく、子クラスで定義された新しいメソッドが実行されます。

これは、共通のインターフェースを持ちつつ、クラスごとに異なる具体的な振る舞いを実装したい場合に非常に有効です。

class Shape {
  draw() {
    return "図形を描画します。";
  }
}

class Circle extends Shape {
  draw() {
    return "円を描画します。"; // 親クラスのdrawメソッドをオーバーライド
  }
}

class Rectangle extends Shape {
  draw() {
    return "長方形を描画します。"; // 親クラスのdrawメソッドをオーバーライド
  }
}

const shapes = [new Shape(), new Circle(), new Rectangle()];
shapes.forEach(shape => console.log(shape.draw()));
// 出力:
// 図形を描画します。
// 円を描画します。
// 長方形を描画します。

上記の例では、ShapeCircleRectangleの各インスタンスに対して同じdraw()メソッドを呼び出していますが、それぞれのオブジェクト型に応じて異なる結果が返されています。この性質を「多態性(ポリモーフィズム)」と呼びます。

多態性により、コードは非常に柔軟になり、様々な型のオブジェクトを統一的に扱うことができるようになります。これは、大規模なアプリケーション開発において、保守性と拡張性の高い設計を実現するための重要な概念です。

JavaScriptクロージャの奥深さ:関数とスコープの関係

JavaScriptのクロージャは、言語の最も強力で理解しがいのある機能の一つです。多くの開発者がその概念を難解だと感じることがありますが、一度理解すれば、非常に柔軟で表現力豊かなコードを書くための強力なツールとなります。

簡単に言えば、クロージャとは「関数とその関数が定義されたレキシカル環境(静的スコープ)への参照を組み合わせたもの」です。これにより、関数はそれが定義されたスコープ内の変数に、そのスコープが終了した後でもアクセスし続けることができます。

この特性は、プライベート変数のエミュレーション、関数の部分適用、状態を持つ関数の作成など、多岐にわたる応用を可能にします。クロージャはJavaScriptの非同期処理やイベントハンドリングの基盤としても機能しており、その理解はJavaScriptを深く学ぶ上で不可欠です。

クロージャの定義とレキシカルスコープ

クロージャは「関数とその関数が定義されたスコープ(レキシカル環境)への参照を組み合わせたもの」と定義されます。これはどういうことでしょうか?

JavaScriptでは、関数はそれが定義された場所のスコープ(レキシカルスコープ)を記憶しています。そして、その関数がそのレキシカルスコープの外で実行されたとしても、定義時に記憶したスコープ内の変数にアクセスし続けることができるのです。この「記憶されたスコープとそれを利用できる関数」のペアこそがクロージャの本質です。

function makeGreeter(greeting) {
  function greet(name) {
    return `${greeting}, ${name}!`;
  }
  return greet; // greet関数は外側のgreeting変数を記憶している
}

const sayHello = makeGreeter('Hello');
console.log(sayHello('Alice')); // Hello, Alice!

const sayHi = makeGreeter('Hi');
console.log(sayHi('Bob'));    // Hi, Bob!

上記の例では、makeGreeter関数が実行を終えても、その内部で定義されたgreet関数は、makeGreeterの引数greetingの値を記憶し続けています。sayHellosayHiはそれぞれ異なるgreetingの値を記憶したクロージャとなっています。

参考情報: MDN Web Docs JavaScript ガイド – クロージャ

状態の保持とプライベート変数

クロージャの最も強力な特性の一つは、それが定義された時点での外部スコープの変数を「状態」として保持し続けられることです。これにより、関数が実行されるたびにその状態を更新したり参照したりすることが可能になります。

この特性を利用すると、プライベート変数をエミュレートすることができます。JavaScriptには、他のオブジェクト指向言語にあるような厳密な「private」修飾子はありませんが、クロージャを使うことで、外部から直接アクセスできない変数を実現できます。

function createCounter() {
  let count = 0; // この変数は外部から直接アクセスできない

  return {
    increment: function() {
      count++;
      return count;
    },
    decrement: function() {
      count--;
      return count;
    },
    getCount: function() {
      return count;
    }
  };
}

const counter = createCounter();
console.log(counter.increment()); // 1
console.log(counter.increment()); // 2
console.log(counter.getCount());  // 2
// console.log(counter.count); // undefined - countはプライベート

createCounter関数が返すオブジェクトのメソッドを通してのみ、count変数にアクセス・変更できます。count変数はcreateCounterのスコープ内に閉じ込められており、外部からは直接参照できないため、データ隠蔽(カプセル化)を実現しています。これは、モジュールパターンなど、多くのデザインパターンで活用される基本的な考え方です。

クロージャの活用例(ファクトリ関数、カウンターなど)

クロージャは多岐にわたる場面で利用されますが、特に役立つ具体的な活用例をいくつか紹介します。

  • ファクトリ関数(Factory Function):

    上記で説明したcreateCounterのような関数は、クロージャを利用して状態を保持するオブジェクトを生成する「ファクトリ関数」の一例です。これにより、複数の独立したカウンターを簡単に作成できます。

    const counter1 = createCounter();
    const counter2 = createCounter();
    console.log(counter1.increment()); // 1
    console.log(counter2.increment()); // 1 (counter1とは独立している)
    
  • イベントハンドラ:

    DOMイベントリスナーを設定する際、クロージャはイベント発生時に特定のコンテキストや変数を保持するために使われます。例えば、ループ内でボタンにイベントリスナーを追加し、それぞれのボタンが異なるIDを記憶して処理を行うような場合です。

    function setupButton(id) {
      document.getElementById(id).addEventListener('click', function() {
        console.log(`ボタン ${id} がクリックされました!`); // idを記憶している
      });
    }
    // setupButton('myButton1'); // HTMLにmyButton1があれば機能する
    
  • 部分適用(Partial Application)/ カリー化(Currying):

    関数が受け取る引数を事前に一部だけ渡し、残りの引数は後で渡す新しい関数を生成する際にもクロージャが利用されます。これは、汎用的な関数を特定の用途に特化した関数に変換するのに便利です。

    function multiply(a) {
      return function(b) { // クロージャ
        return a * b;
      };
    }
    const double = multiply(2);
    console.log(double(5)); // 10
    

このように、クロージャはJavaScriptにおいて、強力なカプセル化、状態管理、関数合成のパターンを実現するための重要な基盤となります。

コールバック関数:非同期処理の基本をマスター

JavaScriptはシングルスレッドで動作する言語でありながら、ユーザーインターフェースがフリーズすることなく、時間のかかるネットワークリクエストやファイル操作などの「非同期処理」を効率的にこなすことができます。この非同期処理の実現において、中心的な役割を果たすのが「コールバック関数」です。

コールバック関数とは、簡単に言えば「後で呼び出されるために、別の関数に引数として渡される関数」のことです。非同期処理だけでなく、イベントハンドリングや配列の反復処理など、JavaScriptの多くの場面で利用される基本的なパターンです。

そのシンプルさゆえに多用されてきましたが、複雑な非同期処理が連鎖すると「コールバック地獄(Callback Hell)」と呼ばれる可読性の低いコードを生み出す原因にもなりました。しかし、その基本的な概念は、Promiseやasync/awaitといった現代的な非同期処理メカニズムを理解するための土台となります。

コールバック関数の基本と役割

コールバック関数は、他の関数の引数として渡され、その引数を受け取った関数内で「後で」実行される関数のことです。これはJavaScriptの関数が「ファーストクラスオブジェクト」である(変数に代入したり、引数として渡したり、戻り値として返したりできる)という特性に基づいています。

コールバックの主な役割は、ある処理が完了した後に実行すべき次の処理を、事前に渡しておくことにあります。これにより、プログラムの実行フローを柔軟に制御できるようになります。

最も身近な例としては、setTimeout関数や配列のforEachメソッドが挙げられます。

  • setTimeoutの例:

    指定したミリ秒数が経過した後に特定の関数を実行します。

    console.log('処理開始');
    setTimeout(function() { // この無名関数がコールバック関数
      console.log('2秒後に実行されました');
    }, 2000);
    console.log('別の処理を実行中...');
    
  • forEachの例:

    配列の各要素に対して、指定した関数(コールバック関数)を実行します。

    const numbers = [1, 2, 3];
    numbers.forEach(function(num) { // この無名関数がコールバック関数
      console.log(num * 2);
    });
    

これらの例からわかるように、コールバック関数は、特定のイベントや条件が満たされたときに実行されるべき動作を定義するのに非常に便利です。

非同期処理におけるコールバックの利用

JavaScriptがシングルスレッドで動作するということは、一度に一つのタスクしか実行できないことを意味します。しかし、ウェブアプリケーションでは、データの取得(ネットワークリクエスト)、ファイルの読み書き、タイマー処理など、時間がかかる処理が頻繁に発生します。

これらの時間のかかる処理を同期的に実行してしまうと、その間UIがフリーズしてしまい、ユーザー体験が著しく損なわれます。そこでコールバック関数が非同期処理の解決策として導入されました。

非同期処理では、時間のかかるタスクを開始した後、すぐに次のコードの実行に移ります。タスクが完了すると、JavaScriptのイベントループがコールバック関数を検出し、その関数を呼び出します。

  • AJAX(非同期JavaScript + XML)リクエストの例:

    サーバーからデータを取得する際によく利用されました。

    function fetchData(url, callback) {
      const xhr = new XMLHttpRequest();
      xhr.open('GET', url);
      xhr.onload = function() { // データが読み込まれた時に実行されるコールバック
        if (xhr.status === 200) {
          callback(null, JSON.parse(xhr.responseText));
        } else {
          callback(new Error('データ取得エラー: ' + xhr.status));
        }
      };
      xhr.onerror = function() { // エラー発生時に実行されるコールバック
        callback(new Error('ネットワークエラー'));
      };
      xhr.send();
    }
    
    fetchData('https://api.example.com/data', function(error, data) {
      if (error) {
        console.error(error.message);
      } else {
        console.log('データを受信しました:', data);
      }
    });
    

このように、コールバックは「この処理が終わったら、次にこの関数を実行してね」という指示を、時間のかかる処理に与える役割を担っています。

注意点とPromise/async-awaitへの発展

コールバック関数は非同期処理の基盤として非常に重要ですが、複雑な非同期処理が連鎖すると、コードの可読性や保守性が著しく低下するという問題に直面します。これが一般的に「コールバック地獄(Callback Hell)」と呼ばれる現象です。

複数の非同期処理が順番に実行される必要がある場合、コールバックがネストされて深いインデントになり、どのコールバックが何のために存在しているのか、またエラーハンドリングをどのように行うべきかなどが非常に分かりにくくなります。

asyncOperation1(function(result1) {
  asyncOperation2(result1, function(result2) {
    asyncOperation3(result2, function(result3) {
      // さらに深くネスト...
      console.log('最終結果:', result3);
    }, handleError);
  }, handleError);
}, handleError);

この問題に対処するため、JavaScriptのコミュニティはより洗練された非同期処理のパターンを開発してきました。

  • Promise (プロミス):

    ES6で導入されたPromiseは、非同期処理の最終的な完了(または失敗)を表すオブジェクトです。チェーン可能なメソッド(.then().catch().finally())を提供し、コールバックのネストを平坦化し、エラーハンドリングを改善します。

    asyncOperation1()
      .then(result1 => asyncOperation2(result1))
      .then(result2 => asyncOperation3(result2))
      .then(result3 => console.log('最終結果:', result3))
      .catch(error => console.error(error));
    
  • async/await (アシンク/アウェイト):

    ES2017で導入されたasync/awaitは、Promiseを基盤としていますが、非同期コードをあたかも同期コードのように書けるようにする構文シュガーです。これにより、非同期処理のコードが非常に読みやすくなります。

    async function performOperations() {
      try {
        const result1 = await asyncOperation1();
        const result2 = await asyncOperation2(result1);
        const result3 = await asyncOperation3(result2);
        console.log('最終結果:', result3);
      } catch (error) {
        console.error(error);
      }
    }
    performOperations();
    

現代のJavaScript開発では、async/awaitが非同期処理の記述における推奨される方法となっていますが、その根底にはコールバックとPromiseの概念が不可欠です。コールバックの理解は、JavaScriptの非同期処理全体を深く理解するための出発点と言えるでしょう。

JavaScriptの便利な小技集:コメント、文字列操作、数値計算

JavaScriptプログラミングをより効率的かつクリーンに行うためには、言語の基本構文だけでなく、日常的に役立つ「小技」やベストプラクティスを知っておくことが重要です。

この記事の最後に、コードの可読性を高めるコメントの書き方、頻繁に利用する文字列操作のメソッド、そして数値計算における注意点や便利なテクニックをまとめて紹介します。これらの知識は、日々のコーディング作業をスムーズにし、より高品質なコードを書くのに役立つでしょう。

小さな工夫の積み重ねが、最終的には大規模なプロジェクトの成功に繋がります。

コードの可読性を高めるコメントの書き方

コメントは、コードが「何をしているか」ではなく、「なぜそのようにしているか」を説明するために存在します。適切に書かれたコメントは、将来の自分や他の開発者がコードを理解し、保守する上で不可欠な要素です。

JavaScriptでは、以下の2種類のコメントが使用できます。

  • 単一行コメント(//:

    行の残りの部分をコメントアウトします。短い説明や、特定の行の挙動を補足するのに適しています。

    const pi = 3.14; // 円周率を定義
    
  • 複数行コメント(/* ... */:

    /**/で囲まれた範囲をコメントアウトします。関数の目的、複雑なロジックの説明、一時的なコードブロックの無効化など、より長い説明に適しています。

    /*
     * この関数はユーザーの名前と年齢を受け取り、
     * 挨拶メッセージを生成して返します。
     * 入力値の検証も行われます。
     */
    function createUserMessage(name, age) {
      // ...
    }
    

コメントを書く際のポイント:

  • なぜ?を説明する: コードを見ればわかる「何」ではなく、その設計判断や意図など「なぜ」を説明する。
  • 最新の状態に保つ: コードが変更されたら、コメントも更新する。古いコメントは誤解を招く原因となる。
  • 短く簡潔に: 長すぎるコメントは読まれにくい。箇条書きや短いフレーズで情報を伝える。
  • JSDocの活用: 公開するAPIやライブラリでは、JSDocのような形式でコメントを書くことで、自動的にドキュメントを生成できます。

コメントは多すぎても少なすぎても問題です。バランス良く、価値のある情報を提供するように心がけましょう。

文字列操作の便利なメソッド

JavaScriptで文字列を扱う機会は非常に多く、文字列オブジェクトには便利な操作メソッドが多数用意されています。これらを使いこなすことで、コードを簡潔かつ効率的に記述できます。

代表的なメソッドをいくつか紹介します。

メソッド 説明
length 文字列の長さを取得 'hello'.length; // 5
charAt(index) 指定したインデックスの文字を取得 'hello'.charAt(0); // 'h'
indexOf(substring) 部分文字列が最初に出現するインデックスを取得。見つからなければ-1 'hello world'.indexOf('world'); // 6
slice(start, end) 文字列の一部を抽出 'hello world'.slice(0, 5); // 'hello'
substring(start, end) 文字列の一部を抽出(sliceと似ているが負のインデックスの扱いが異なる) 'hello world'.substring(6); // 'world'
replace(old, new) 指定した文字列を別の文字列で置換 'hello world'.replace('world', 'JS'); // 'hello JS'
split(separator) 指定した区切り文字で文字列を分割し、配列として返す 'apple,banana'.split(','); // ['apple', 'banana']
toUpperCase() 文字列をすべて大文字に変換 'hello'.toUpperCase(); // 'HELLO'
toLowerCase() 文字列をすべて小文字に変換 'HELLO'.toLowerCase(); // 'hello'
trim() 文字列の先頭と末尾の空白を除去 ' hello '.trim(); // 'hello'
テンプレートリテラル バックティック記号 (` `) を使った文字列結合と埋め込み const name = 'Alice'; `Hello, ${name}!`; // 'Hello, Alice!'

これらのメソッドを適切に活用することで、文字列の加工や整形が非常に効率的に行えます。

数値計算のテクニックと注意点

JavaScriptでの数値計算は基本的に直感的ですが、浮動小数点数の扱いや型の変換において、いくつか注意すべき点と便利なテクニックがあります。

  1. 浮動小数点数の精度問題:

    JavaScriptの数値はすべて倍精度浮動小数点数(IEEE 754形式)として扱われます。これにより、特定の小数点の計算で予期しない結果が生じることがあります。

    console.log(0.1 + 0.2); // 0.30000000000000004 (0.3ではない)
    

    このような場合、結果を固定小数点数に変換するtoFixed()メソッドや、計算前に整数に変換するなどの工夫が必要です。

    console.log((0.1 + 0.2).toFixed(2)); // '0.30' (文字列として返される)
    
  2. Mathオブジェクトの活用:

    Mathオブジェクトは、数学的な定数(例: Math.PI)や関数(例: Math.random()Math.floor()Math.ceil()Math.round()Math.max()Math.min()など)を提供します。乱数の生成や数値の丸め処理などで頻繁に利用されます。

    console.log(Math.random());       // 0以上1未満の乱数
    console.log(Math.floor(4.7));     // 4 (小数点以下を切り捨て)
    console.log(Math.round(4.4));     // 4 (四捨五入)
    console.log(Math.max(10, 20, 5)); // 20
    
  3. 数値への型変換:

    文字列から数値への変換には、parseInt()parseFloat()、または単項プラス演算子(+)がよく使われます。

    • parseInt('123'): 整数に変換。
    • parseFloat('12.34'): 浮動小数点数に変換。
    • +'123': 最も簡潔な数値変換。
    const strNum = '123';
    console.log(typeof strNum); // string
    console.log(typeof parseInt(strNum)); // number
    console.log(typeof +strNum); // number
    
  4. isNaN()Number.isNaN():

    ある値が数値として有効でない(Not-a-Number)かをチェックするには、isNaN()関数やNumber.isNaN()メソッドを使用します。Number.isNaN()の方が厳密なチェックを行います。

    console.log(isNaN('hello')); // true
    console.log(Number.isNaN('hello')); // false (string型のため)
    console.log(Number.isNaN(NaN)); // true
    

これらのテクニックと注意点を理解することで、JavaScriptでの数値計算をより正確かつ意図通りに行うことができます。