「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > JavaScript の主なバグ (およびその回避方法)

JavaScript の主なバグ (およびその回避方法)

2024 年 9 月 12 日に公開
ブラウズ:925

Top iggest Bugs in JavaScript (And How to Avoid Them)

JavaScript は非常に強力で適応性のある言語ですが、検出が難しい問題が発生する可能性もあります。このブログ記事では、開発者が JavaScript を使用する際に発見する最も一般的な 5 つの欠陥と、これらの問題の理由と解決策を見ていきます。経験豊富な開発者でも、初心者でも、これらの一般的な危険性を知っていれば、トラブルシューティングにかかる​​時間を節約できます。

このブログ記事は @hackyrupesh としても知られる Rupesh Sharma によって作成されました。

1. 意図しないグローバル変数

問題

JavaScript では、明示的に宣言せずに変数を定義できるため、意図しないグローバル変数が作成される可能性があります。これは、競合やデバッグ困難なエラーを引き起こす可能性があるため、大規模なコードベースや複数の開発者と作業する場合に特に問題になります。

function setUserName() {
    userName = "Alice"; // userName is now a global variable
}

setUserName();
console.log(userName); // Outputs: "Alice"

上記の例では、userName が var、let、const なしで宣言されているため、自動的にグローバル変数になります。これにより、特に userName が後でコード内の別の場所で使用される場合、予期しない動作が発生する可能性があります。

解決策

常に let、const、または var を使用して変数を宣言します。これにより、変数がローカルかグローバルかが明確になり、誤ってグローバル変数を使用することを防ぎます。

function setUserName() {
    let userName = "Alice"; // userName is now a local variable
}

setUserName();
console.log(userName); // ReferenceError: userName is not defined

参考文献

  • Mozilla Developer Network (MDN): JavaScript 変数

2. このキーワードの悪用

問題

JavaScript の this の値は、関数が呼び出されるコンテキストに応じて変化する可能性があります。これにより、特にコールバックまたはイベント ハンドラーを使用する場合に、予期しない動作が発生する可能性があります。

const user = {
    name: "Alice",
    greet: function() {
        console.log(`Hello, my name is ${this.name}`);
    }
};

setTimeout(user.greet, 1000); // Outputs: "Hello, my name is undefined"

この例では、greet 内の this キーワードは、setTimeout へのコールバックとして渡されるときに、ユーザー オブジェクトではなくグローバル オブジェクト (または厳密モードでは未定義) を参照します。

解決策

アロー関数またはbind()を使用して、これが正しいオブジェクトにバインドされたままであることを確認します。

setTimeout(user.greet.bind(user), 1000); // Outputs: "Hello, my name is Alice"

あるいは、アロー関数を使用しても、独自の this コンテキストがないため、問題を解決できます。

const user = {
    name: "Alice",
    greet: function() {
        setTimeout(() => console.log(`Hello, my name is ${this.name}`), 1000);
    }
};

user.greet(); // Outputs: "Hello, my name is Alice"

参考文献

  • MDN: これは JavaScript です

3. 未定義とヌルの混乱

問題

JavaScript には未定義と null の両方があり、これらが同じ意味で使用されたり、適切にチェックされなかったりすると、混乱やバグが発生する可能性があります。

let user = {
    name: "Alice",
    age: null
};

if (user.age) {
    console.log(`User's age is ${user.age}`);
} else {
    console.log("Age is not provided");
}
// Outputs: "Age is not provided"

ここでは、user.age は null ですが、if 条件では false として扱われます。 null が有効な状態であることを意図している場合、これにより問題が発生する可能性があります。

解決策

アプリケーション内で両方が有効な値である場合は、常に未定義と null を明示的にチェックしてください。

if (user.age !== null && user.age !== undefined) {
    console.log(`User's age is ${user.age}`);
} else {
    console.log("Age is not provided");
}

厳密な等価性 (===) を使用すると、未定義と null を区別するのにも役立ちます。

参考文献

  • MDN: Null
  • MDN: 未定義

4. コールバック地獄

問題

コールバック関数は、JavaScript で非同期操作を処理する一般的な方法です。ただし、それらが互いに入れ子になっている場合、「コールバック地獄」と呼ばれる、深く入れ子になった構造が作成される可能性があります。これにより、コードの読み取り、保守、デバッグが困難になります。

doSomething(function(result1) {
    doSomethingElse(result1, function(result2) {
        doAnotherThing(result2, function(result3) {
            doFinalThing(result3, function(finalResult) {
                console.log(finalResult);
            });
        });
    });
});

この深く入れ子になった構造は追跡するのが難しく、デバッグするのはさらに困難です。

解決策

Promises または async/await を使用して構造を平坦化し、コードを読みやすくします。

doSomething()
    .then(result1 => doSomethingElse(result1))
    .then(result2 => doAnotherThing(result2))
    .then(result3 => doFinalThing(result3))
    .then(finalResult => console.log(finalResult))
    .catch(error => console.error(error));

または、async/await を使用します:

async function executeTasks() {
    try {
        const result1 = await doSomething();
        const result2 = await doSomethingElse(result1);
        const result3 = await doAnotherThing(result2);
        const finalResult = await doFinalThing(result3);
        console.log(finalResult);
    } catch (error) {
        console.error(error);
    }
}

executeTasks();

参考文献

  • MDN: 約束
  • MDN: 非同期/待機

5. 浮動小数点精度の問題

問題

JavaScript は数値の表現に IEEE 754 標準を使用するため、特に浮動小数点演算で精度の問題が発生する可能性があります。これにより、計算で予期しない結果が生じる可能性があります。

console.log(0.1   0.2); // Outputs: 0.30000000000000004
console.log(0.1   0.2 === 0.3); // Outputs: false

浮動小数点精度の誤差により、0.1 0.2 の結果は正確に 0.3 になりません。

解決策

これを回避するには、結果を固定の小数点以下の桁数に丸めることができます。

function isEqual(a, b) {
    return Math.abs(a - b) 



または、演算を実行する前に数値をスケーリングし、その後スケーリングして戻すことで整数を操作します。

console.log((0.1 * 10   0.2 * 10) / 10); // Outputs: 0.3

参考文献

  • MDN: Number.EPSILON
  • 浮動小数点演算の問題

結論

JavaScript は特異性と隠れたリスクに満ちた言語ですが、最も頻繁に発生する欠陥とそれらを回避する方法を知っていれば、よりクリーンで信頼性の高いコードを開発できます。不要なグローバル変数から浮動小数点の精度の問題まで、これらの欠陥はそれぞれ、対処しないと大きな問題を引き起こす可能性があります。ただし、適切なコーディング方法と適切なツールを使用すると、これらの懸念を軽減し、JavaScript コードの回復力を高めることができます。

このブログは Chatgpt によって書かれました ??

リリースステートメント この記事は次の場所に転載されています: https://dev.to/hackyrupesh/top-5-biggest-bugs-in-javascript-and-how-to-avoid-them-af7?1 侵害がある場合は、study_golang までご連絡ください。 @163.com 削除
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3