2017-01-03 49 views
1

更新: FelixKling正确地指出我使用的术语spread operator不正确,应该是Rest Parameter。使用我链接到的兼容性表格,它清楚地显示Rest Parameter在Safari 9中不被支持。澄清它是Rest Parameter是这个问题的真正答案(尽管如何重写函数的例子非常好)。ES6 Spread运算符(Rest参数) - 语法在Safari 9中失败


我写了一个javascript函数性能测试器,它测试函数运行多长时间。它使用ES6扩展运算符(...),它在Firefox中运行良好,但在Safari中运行良好(高达9.1.2版本)。根据这compatibility chart,Safari 9得到了9/15的分数运算符,我认为这是Safari 9的一个缺点。是否有ES6的方式来重写它,所以它将与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扩大。 “在字符串中,在函数调用中”是一个没有 –

+0

它可以像使用函数timerTest(func,迭代)替换'timerTest(func,iterations,... someData)一样简单var someData = Array.prototype。 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);'然后将'args'传递给'func.apply(this,args);' – mseifert

+0

@ mseifert对,如果你测量时间,在循环内部创建数组根本不是一个好主意,我想我只是为了可读性而调用函数之前才放置代码。我刚刚编辑了我的答案。 –