2017-01-03 3 views
1

更新: FelixKlingは、spread operatorという用語の使用が間違っていて、Rest Parameterであると正しく指摘しています。私がリンクしている互換性表を使用すると、Rest ParameterがSafari 9でサポートされていないことがはっきりとわかります。Rest Parameterであることを明確にしています(機能の書き換え方法の例は優れていますが)。ES6スプレッドオペレータ(Rest Parameter) - Safari 9で構文が失敗する


私は関数の実行時間をテストするjavascript関数のパフォーマンステスターを作成しました。それは、ES6のスプレッド演算子(...)を使用し、Firefoxではうまく動作しますが、Safari(バージョン9.1.2まで)では動作しません。このcompatibility chartによれば、Safari 9は普及した演算子のスコアが9/15であり、これはSafari 9の欠点であると推測しています。Safari 9で動作するように書き直す方法はありますか? 9/15の「9」 - それはある状況では機能していたに違いないと思います)

function timerTest(func, iterations, ...someData) { 
    if (typeof iterations == "undefined") { 
     iterations = 1; 
    } 
    var start = performance.now(); 
    for (var i = 0; i < iterations; i++) { 
     func.apply(this, someData); 
    } 

    var funcName = /function ([^\(]+)/.exec(func.toString())[0]; 
    v("Time to run " + funcName + " for " + iterations + " time(s): " + (performance.now() - start)); 
    return performance.now() - start; 
} 

それは(要素が割り当てられたクラスを持っているかどうかをテストするために高速である3つの方法のかを決定する、この場合には)どのように使用されるかのサンプル:

var e = document.getElementById("test"); 
timerTest(hasClass, 1000000, e, "x"); 
timerTest(hasClass2, 1000000, e, "x"); 
timerTest(hasClass3, 1000000, e, "x"); 

function hasClass(e, name) { 
    if (typeof e !== "undefined" && typeof e.className !== "undefined") { 
     return new RegExp('(\\s|^)' + name + '(\\s|$)').test(e.className); 
    } 
    return false; 
} 

function hasClass2(e, name) { 
    if (typeof e !== "undefined" && typeof e.className !== "undefined") { 
     return (' ' + e.className + ' ').indexOf(' ' + name + ' ') > -1; 
    } 
    return false; 
} 

function hasClass3(e, name) { 
    if (typeof e !== "undefined" && typeof e.classList !== "undefined") { 
     return e.classList.contains(name) 
    } 
    return false; 
} 
+2

は9/15をクリックして展開します。 "関数呼び出しでの文字列の使用"はno –

+0

です。関数timerTest(func、iterations){ var someData = Array.prototypeで 'timerTest(func、iterations、... someData)を置き換えるだけで簡単にできます。 slice.call(arguments、2); ...} '。 – RobG

+0

@jeffcarey - ああ、私は9/15をクリックして拡大したことに気付かなかった。この機能を紹介してくれてありがとう。これにより、私にはどのようなオプションがあるかがわかります。 – mseifert

答えて

-1

使用argumentsオブジェクト

// call your timerTest function 
timerTest(hasClass, 1000000, e, "x"); 

function timerTest(func, iterations) { 

    if (typeof iterations == "undefined"){ 
    iterations = 1; 
    } 
    var start = performance.now(); 
    //Get parameters from arguments 
    var args = Array.prototype.slice.call(arguments, 2); 

    for (var i = 0; i < iterations; i++){ 
    func.apply(this, args); 
    } 

    var funcName = /function ([^\(]+)/.exec(func.toString())[0]; 
    v("Time to run " + funcName + " for " + iterations + " time(s): " + (performance.now() - start)); 
    return performance.now() - start; 
} 
+0

この関数は変更に対応していますが、例に示す関数の実行に要する時間を比較すると、メソッドの実行には67%から10倍の時間がかかります。解決方法は 'var args = Array.prototype.slice.call(arguments、2);'を使用して配列に引数を取得し、 'func.apply(this、args);で' args'を渡すことです。 – mseifert

+0

@あなたが時間を測定しているなら、ループ内の配列を作成するのは良い考えではありません。読みやすさのために関数を呼び出す前にコードを置くと思います。私はちょうど私の答えを編集しました。 –

関連する問題