24
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaScript魔法:コードの優雅さと保守性を高める6つの秘訣

Posted at

はじめに

フロントエンド開発エンジニアとして、作業中の細かい点に注意を払うことで、コードの可読性を向上させ、よりエレガントに見せることができます。

今回は、一目で理解できる便利でエレガントなJavaScriptのコツをいくつか紹介します。

これらのコツは、コードの効率性と可読性を向上させることを目的としています。

ソフトウェア開発において、コードの簡素化と可維持性の向上は常に重要な目標です。次の6つの実用的なJavaScriptテクニックを使用して、より効率的なコードを作成できます:if...elseのスパゲッティコードを削減し、冗長なループをパイプライン操作やfindincludesで置き換え、一貫した結果変数を使用し、オブジェクトの整合性を保つ。Apidogは、API管理と自動化の分野で強力なサポートを提供し、複雑なAPIコールの迅速な統合と管理を可能にし、プロジェクトのパフォーマンスを向上させます。JavaScriptテクニックとApidogを組み合わせて使用することで、開発プロセスがより円滑になります。これらの改善を試して、心置きなくコーディングを楽しんでください!

apidog-client-1.png

テクニック1: if...elseロジックの簡素化

2つ以上のif...else文を含む関数を書いている場合、より良い最適化方法があるかどうかを考える時です。

function getPrice(item) {
    if (item === 'apple') return 1.0;
    else if (item === 'banana') return 0.5;
    else if (item === 'orange') return 0.75;
    // さらに条件が続く...
}

このような実装は、多くの条件文で関数の本体を乱雑にする可能性があります。新しいアイテムを追加したい場合、別のif...else文を追加するために関数内のロジックを変更する必要があります。

これは、ある程度、オープン/クローズド原則(OCP)に違反します。OCPによれば、機能を拡張する必要がある場合、既存のコードを変更するのではなく、ソフトウェアエンティティを拡張することで要件の変更を達成することを目指すべきです。

これは古典的な最適化戦略です。Mapに似たデータ構造を使用してすべてのアイテムを保存することができます。ここでは、データを保存するために直接オブジェクトを作成できます。

const priceMap = {
    apple: 1.0,
    banana: 0.5,
    orange: 0.75,
    // さらにアイテムが続く...
};

function getPrice(item) {
    return priceMap[item] || 0; // アイテムが見つからない場合は0を返す
}

このアプローチにより、新しいアイテムを追加する必要がある場合でも、getPriceのような関数のコアロジックを変更する必要がありません。

実際、多くの人は必要な場所で直接foodMapのようなものを使用することを好みます。ここでは、この思考プロセスを説明するために単純な例を使用しています。

const priceMap = new Map();
priceMap.set('apple', 1.0);
priceMap.set('banana', 0.5);
priceMap.set('orange', 0.75);

function getPrice(item) {
    return priceMap.get(item) || 0; // アイテムが見つからない場合は0を返す
}

テクニック2: 冗長なループをパイプライン処理で置き換える

const foods = [
    { name: 'Apple', group: 1 },
    { name: 'Banana', group: 2 },
    { name: 'Carrot', group: 1 },
    // さらにアイテムが続く...
];

const group1Foods = [];
for (let i = 0; i < foods.length; i++) {
    if (foods[i].group === 1) {
        group1Foods.push(foods[i].name);
    }
}

従来は、配列を反復処理し、各アイテムのグループを確認し、結果を蓄積するためにforループを使用することがありました。

この方法は機能しますが、冗長で可読性の低いコードになる可能性があります。filtermapのようなメソッドを使用することで、コードをより簡潔にするだけでなく、意味の明確さも向上させることができます。

この方法では、まず配列をフィルタリングし、その後再構築するプロセスが即座に明確になります。

const group1Foods = foods
    .filter(food => food.group === 1)
    .map(food => food.name);

テクニック3: findメソッドの活用

上記の例を続けて、特定のプロパティ値に基づいて食品オブジェクトの配列から特定の食品を検索したい場合、findの有用性が明らかになります。

例:
特定のアイテムを検索するためにforループを使用する代わりに:

const foods = [
    { name: 'Apple', group: 1 },
    { name: 'Banana', group: 2 },
    { name: 'Carrot', group: 1 },
    // さらにアイテムが続く...
];

let foundFood;
for (let i = 0; i < foods.length; i++) {
    if (foods[i].name === 'Banana') {
        foundFood = foods[i];
        break;
    }
}

単にfindを使用できます:

const foundFood = foods.find(food => food.name === 'Banana');

findメソッドを使用すると、提供されたテスト関数を満たす配列内の最初の要素を迅速に見つけることができ、従来のループに比べてよりクリーンで効率的な代替手段を提供します。

テクニック4: includesで存在確認を簡単に

配列に特定の値が含まれているかどうかを確認する必要がある場合、includesメソッドを使用することでコードを大幅に簡素化できます。要素の存在を確認するためにループで配列を反復処理する代わりに、includesを使用することで同じ結果をより効率的かつ可読性の高い方法で達成できます。

例:

配列に特定の要素が含まれているかどうかを判断するためにforループを使用する代わりに:

const fruits = ['Apple', 'Banana', 'Carrot'];
let hasBanana = false;
for (let i = 0; i < fruits.length; i++) {
    if (fruits[i] === 'Banana') {
        hasBanana = true;
        break;
    }
}

単にincludesを使用できます:

const hasBanana = fruits.includes('Banana');

includesを使用することで、コードの量を減らすだけでなく、配列内の値の存在を確認するという意図を明確に示すことができます。

この方法は、従来のループを使用した場合に比べて、より冗長なプロセスをエレガントに解決します。

特に、頻繁にメンバーシップテストを行う必要がある配列を扱う場合に役立ち、よりクリーンでメンテナブルなコードを書くのに役立ちます。

テクニック5: 一貫した返却変数の使用

特に小さな関数では、返却値に一貫した変数名(例えばresult)を使用することがベストプラクティスです。これにより、返却値がどこから来ているのかが明確になり、あなたや他の人が簡単に認識できる標準化された命名規則を提供します。

function calculateTotal(items) {
    let result = 0;
    for (let i = 0; i < items.length; i++) {
        result += items[i].price;
    }
    return result;
}

テクニック6: オブジェクトの整合性を維持する

バックエンドリクエストから返されたデータを処理する際、特定の属性を個別に処理することがよくあります。特に処理が必要なプロパティが少ない場合に一般的です。多くの開発者は、操作に必要な属性のみを抽出する傾向がありますが、これは最初の方法です。しかし、この方法は長期的には非現実的です。

関数が後で追加の依存関係を必要とするかどうかが不確かな場合、オブジェクト全体の整合性を維持することが望ましいです。例えば、関数getDocDetailが現在iconcontentのようなプロパティを使用している場合、将来的にtitledateなどの属性が必要になるかもしれません。個々のプロパティではなく、完全なオブジェクトを渡すことで、パラメータリストの長さを短縮するだけでなく、コードの可読性と柔軟性を向上させます。

例:

必要な属性のみを抽出して渡す代わりに:

function getDocDetail(icon, content) {
    // iconとcontentを処理
}

const doc = { icon: 'icon.png', content: 'Some content', title: 'Document Title', date: '2023-10-15' };
getDocDetail(doc.icon, doc.content);

オブジェクト全体を渡す方が良いです:

function getDocDetail(doc) {
    const { icon, content } = doc;
    // iconとcontentを処理
    // 将来的に必要な場合はdoc.title, doc.dateなどにアクセス
}

const doc = { icon: 'icon.png', content: 'Some content', title: 'Document Title', date: '2023-10-15' };
getDocDetail(doc);

このアプローチは、関数のシグネチャを変更することなく、追加のプロパティに簡単にアクセスできるようにすることで、関数を将来に備えます。新しい要件が発生するにつれて、関数パラメータを継続的に変更する必要がなくなるため、コードがより堅牢でメンテナブルになります。このプラクティスはモジュール設計の原則をサポートし、クリーンでスケーラブルなコードベースに貢献します。

最後に

上記で共有したJavaScriptのテクニックは、コードの品質と安定性を効果的に向上させることができます。冗長なループの削減、オブジェクトの整合性の維持、filtermapfindincludesなどのモダンなJavaScriptメソッドの使用など、これらの戦略を実装することで、よりクリーンで効率的、かつメンテナブルなコードを作成できます。これらのプラクティスは、コーディングプロセスを簡素化するだけでなく、ベストプラクティスに沿ったものとなり、アプリケーションをより堅牢で変化に適応しやすいものにします。

次のプロジェクトでこれらのコツを試してみて、改善を実感してください。コーディングを楽しんでください!

24
20
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?