3

Javascriptで重複する関数を検出することは可能ですか(場合によっては誤って記述されている可能性があります)?Google Chromeでは、

printLah(); //this prints "Haha" for some reason, without even printing an error message in the Javascript console!
function printLah(){
    alert("Hahah!");
}


function printLah(){
    alert("Haha");
}

こちらはJSfiddleです。

4

3 に答える 3

9

簡単に言えば、そうではありません

これがjavascriptの仕組みです。関数名は、関数が割り当てられた単なる変数です。例えば:

function foo () {
    alert('foo!');
}

foo = 1;

foo();

数値は関数ではないため、上記のコードはエラーを生成します。関数名と変数名に違いはありません。実際、関数を定義する別の方法は、変数を定義する方法とまったく同じです。

var foo = function () {
              alert('foo!');
          }

javascriptが再割り当てを防ぐことができないのは、このファーストクラスオブジェクトとしての関数の動作のためです。そうしないと、変数を再割り当てできません(一方、純粋関数型言語では、変数の再割り当てを禁止しても問題はありません)。


回避策とベストプラクティス:

これが、JavaScriptであまり多くのグローバルを定義するべきではないと人々が言い続ける理由です。これには機能が含まれます。そうしないと、誤って他の人のコードと衝突する可能性があります。

この問題を軽減できるjavascriptには、オブジェクトクロージャという2つの強力な機能があります。

javascriptはオブジェクトをサポートしているため、オブジェクト指向プログラミングを使用して、プログラム内のグローバルの数を制限する必要があります。従来のOOPとは異なり、オブジェクトをコレクションまたは名前空間として使用する場合、javascriptの方がうまく機能します。これは、javascriptにファイルスコープがなく、すべてがグローバルであるためです。

これは、従来のOOPのように小さな問題をカプセル化する小さなオブジェクトを作成するべきではないという意味ではありません。これは、可能であれば、すべてのオブジェクトを1つの親オブジェクトに含める必要があることを意味します。そして、私はここで相続を意味するのではなく、私は持っている関係を意味します。この例については、jQueryやRaphaelなどの人気のあるライブラリをご覧ください。他の人のコードとの衝突を避けるために、1つのオブジェクトのみをグローバルスコープにエクスポートします。

しかし、繰り返しになりますが、これは実際には、オブジェクトを再割り当てすることから人々を保護するものではありません(結局のところ、オブジェクトは変数であるため)。たとえば、JavaScriptの他のビットが実行される前に、HTMLファイルの先頭でこれを行うことでjQueryを簡単に壊すことができます。

jQuery = null;

コードが改ざんされないように保護する方法は、クロージャーを使用することです。サードパーティのコードは、クロージャー内から実行するコードにアクセスできません。つまり、グローバルを回避する限りです。

于 2012-09-11T03:22:58.003 に答える
4

slebetmanの答えを続けるために、変数または関数を宣言する前に、以下を使用して存在を確認できます。

if (typeof(functionName) == 'undefined') {
    functionName = function() { 
        // add code here
    }
}

繰り返しになりますが、このチェックを行う理由は、多くの場合は必要ない場合でも、グローバルスコープに何かを配置する必要があるためです。putsを使用しないvarと、暗黙的にグローバルスコープに入れられます。

于 2012-09-11T03:34:58.270 に答える
-1

これを試してみてください。

$(document).ready(function () {
    var all_functions = [];
    var duplicate_functions = [];
    var reportRecipientsDuplicate = [];
    for (var i in window) {

        if ((typeof window[i]).toString() == "function") {
            if (window[i].name) {
                all_functions.push(window[i].name);
            }
        }
    }

    var all_functions1 = all_functions.sort();


    for (var i = 0; i < all_functions1.length - 1; i++) {
        if (all_functions1[i + 1] == all_functions1[i]) {
            duplicate_functions.push(all_functions1[i]);
        }
    }
    console.log("Duplicate functions on page");
    console.log(duplicate_functions);
});
于 2018-03-01T11:27:23.983 に答える