性能与“更好的实践”:with 语句与带有一堆参数的函数
我最近在 JS 中做了很多模板化工作,所以我总是遇到“邪恶的”with
语句。
它使模板更容易使用,因为您不必在变量前面加上对象。
听说 with 语句不好,而且它们可能导致性能不佳,我开始寻找另一个解决方案:
我的解决方案:带有一堆参数的函数
是我的代码:
var locals = {
name : "Matt",
email : "[email protected]",
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","[email protected]","(555) 555-5555")
注意:这些完成完全相同的事情。两者都是从任何人那里抽象出来的,因此令人讨厌的长参数列表并不是什么大问题。
我想知道哪一个更好:使用 with 语句或可能包含大量参数的函数。
除非有人有更好的解决方案...?
谢谢! 马特·穆勒
I've been doing a lot of templating in JS lately, so I've invariably run across the "evil" with
statement.
It makes templates much easier to work with as you don't have to preface your variables with an object.
Hearing that with statements are bad and also that they may cause poor performance, I set out for another solution:
My Solution: Function with a bunch of parameters
Here's my code:
var locals = {
name : "Matt",
email : "[email protected]",
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","[email protected]","(555) 555-5555")
Note: these accomplish the exact same thing. Both are abstracted away from anyone so an obnoxiously long parameter list is no biggie.
I'm wondering which one is better: using a with statement or a function with the potential for a crazy number of parameters.
Unless someone has a better solution...?
Thanks!
Matt Mueller
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我发现你的解决方案非常臃肿。它完全不简单,而
with
非常简单(一行代码,其本身与对象遍历和数组实例化相比成本非常低)。此外,您的解决方案在制作模板函数(定义其参数)时需要准备好模板对象,在我看来,这可能会不太灵活。
查看MDC。一个设计良好的模板可能具有很少的逻辑和大量的变量引用(如果不是这样,那么它应该是这样!),这使得
with
在这种情况下成为完美的候选者,因为在with
范围内应该很少有其他查找。任何可能获得的额外性能似乎都是微观优化,尽管只是执行一些基准测试而不是理论上的。 http://jsperf.com/with-vs-fn 在基准测试之前执行所有设置代码对于您的版本,但在函数执行期间执行
with
内容,因此这并不公平,尽管即使在最慢的迭代中您也知道它有多快; >400,000 次操作/秒是最慢的。我怀疑你不需要每秒渲染超过 400,000 个模板......I find your solution very bloated. It is totally non-trivial, while
with
is so simple (one line of code which in and of itself has very little cost vs. your object traversal and array instantiations).Moreover, your solution requires a template object ready when making the templating function (to define its parameters), which may prove down the road less flexible in my opinion.
Check out MDC. A well designed template would presumably have little logic and heavy variable references (and if it isn't that way, then it should be!), which makes
with
the perfect candidate in such a situation, because there should be very few other lookups in the scope of thewith
.Any extra performance that may be gained seems like it would be micro-optimisation, although rather than theorise, just perform some benchmarks. http://jsperf.com/with-vs-fn does all the setup code before the benchmark for your version, but performs the
with
stuff during the function execution, so it's not really fair, although even on the slowest iterations you get an idea of how fast it is; >400,000 ops/sec is the slowest. I doub't you need to render more than 400,000 templates a second...你尝试过 JS 模板引擎吗?它们通常非常快,并且可以为您节省一些渲染代码。
我是 pure.js 的作者,它有点原创,但是还有很多其他可用的并且适合任何人品尝。
Have you tried a JS templating engine? They are usually very fast, and save you some rendering code.
I'm the author of pure.js which is a bit original, but there are plenty of others available and for any taste.
with
的问题不是性能,而是歧义和不可预测的行为。例如,请参阅JavaScript 的隐藏功能?
The problems with
with
are not performance, they are ambiguity and unpredictable behaviour.See, for example, Hidden Features of JavaScript?