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

PHPz
リリース: 2024-08-28 06:12:02
オリジナル
1111 人が閲覧しました

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: ヌル
  • MDN: 未定義

4. コールバック地獄

問題

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

doSomething(function(result1) {
    doSomethingElse(result1, function(result2) {
        doAnotherThing(result2, function(result3) {
            doFinalThing(result3, function(finalResult) {
                console.log(finalResult);
            });
        });
    });
});
ログイン後にコピー

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

解決策

Promise または 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) < Number.EPSILON;
}

console.log(isEqual(0.1 + 0.2, 0.3)); // Outputs: true
ログイン後にコピー

または、演算を実行する前に数値をスケールし、その後スケールダウンして整数を操作します。

console.log((0.1 * 10 + 0.2 * 10) / 10); // Outputs: 0.3
ログイン後にコピー

References

  • MDN: Number.EPSILON
  • The Problem with Floating Point Arithmetic

Conclusion

JavaScript is a language full of idiosyncrasies and hidden risks, but knowing the most frequent flaws and how to avoid them allows you to develop cleaner, more dependable code. From unwanted global variables to floating-point accuracy concerns, each of these flaws can create major difficulties if not addressed. However, with proper coding methods and the correct tools, you can reduce these concerns and make your JavaScript code more resilient.

this blog written by Chatgpt ??

以上がJavaScript の主なバグ (およびその回避方法)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート