【问题标题】:Performance & "Better Practice": with statement vs. function with a bunch of parameters性能和“更好的实践”:使用语句与带有一堆参数的函数
【发布时间】:2011-04-14 07:58:12
【问题描述】:

我最近在 JS 中做了很多模板,所以我总是遇到“邪恶”with 声明。

它使模板更易于使用,因为您不必在变量前面加上对象。

听说 with 语句不好,而且它们可能导致性能不佳,我开始寻求另一种解决方案:

我的解决方案:带有一堆参数的函数

这是我的代码:

var locals = {
  name : "Matt",
  email : "wahoo@wahoo.com",
  phone : "(555) 555-5555"
};

var keys = [];
var values = [];

for (key in locals) {
  local = locals[key];

  keys.push(key)
  values.push(local);

}

keys = keys.join(',');

var fn = new Function(keys, "**TEMPLATE STUFF**"); // function(name, email, phone) {...}
fn.apply(this, values); // fn("Matt","wahoo@wahoo.com","(555) 555-5555")

注意:这些完成完全相同的事情。两者都是从任何人那里抽象出来的,所以一个令人讨厌的长参数列表并不是什么大问题。

我想知道哪个更好:使用 with 语句或可能包含大量参数的函数。

除非有人有更好的解决方案...?

谢谢! 马特·穆勒

【问题讨论】:

    标签: javascript templates with-statement


    【解决方案1】:

    我发现您的解决方案非常臃肿。这完全不平凡,而with 非常简单(一行代码本身与您的对象遍历和数组实例化相比成本非常低)。 此外,您的解决方案需要在制作模板函数(以定义其参数)时准备好模板对象,这在我看来可能会变得不那么灵活。

    查看MDC。一个设计良好的模板可能几乎没有逻辑和大量的变量引用(如果不是这样,那么它应该是!),这使得 with 在这种情况下成为完美的候选者,因为应该很少有其他的在with 范围内查找。

    任何可能获得的额外性能似乎都是微优化,尽管不是理论上的,只是执​​行一些基准测试。 http://jsperf.com/with-vs-fn 在您的版本的基准测试之前完成所有设置代码,但在函数执行期间执行 with 的东西,所以这并不公平,尽管即使在最慢的迭代中你也知道它有多快; >400,000 ops/sec 是最慢的。我怀疑您是否需要每秒渲染超过 400,000 个模板...

    【讨论】:

    • 我绝对同意 - 我的解决方案是一个巨大的 hack。它似乎也是我发现的唯一一个提供与with() 相同的结果而没有with() 问题的完全相同 的东西。我真的很喜欢with() - 我认为它真的很优雅,但我确实看到了使用它的危险。附: - 感谢链接,我一直在寻找测试 JS 性能的好方法。
    • 我还认为在模板上下文中使用with 的方式是安全的,因为如果您不定义可能泄漏到全局的变量,它将引发错误。这也只是一个好奇的事情:你在一个函数中有多少个参数可以? :-)
    【解决方案2】:

    你试过 JS 模板引擎吗?它们通常非常快,并且可以为您节省一些渲染代码。

    我是 pure.js 的作者,它有点原创,但还有很多其他的可用且适合任何口味。

    【讨论】:

    • 很荣幸 :-D.. 我昨晚在看你的模板引擎 - 它看起来很漂亮,我喜欢模板只是普通的 html。实际上,我对来自 Node 的修改版 eco 非常满意,这使得语法看起来几乎与 ruby​​ 的模板一模一样。我需要在该上下文中使用 with 以获得所需的语法。
    • 啊...那些希望 Javascript 像 Ruby 一样工作的 Ruby 人!-)
    • 哈哈哈。老实说,我不了解Ruby。我认为您不必了解或喜欢 Ruby 即可欣赏其语法 :-D
    【解决方案3】:

    with 的问题不是性能,而是模棱两可和不可预测的行为。

    例如,请参阅Hidden Features of JavaScript?

    【讨论】:

    • 我一直在挖掘,从我读到的内容来看,它的运行速度确实比写出对象要慢(即 locals.name 与 name)。我的猜测是因为它会尝试在两个地方而不是一个地方写它。我真的很想知道......好吧,什么更快?
    • 我已经读到 DoU 和 DoT 模板因为这个原因而避免使用 - github.com/olado/doT
    猜你喜欢
    • 2018-02-09
    • 2021-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-06
    相关资源
    最近更新 更多