有多少全局变量可以传递给 IIFE 包装器?

How many globals make sense to be passed to the IIFE wrapper?

将大量全局值传递给 IIFE 在多大程度上有意义?

据我所见(window,文档和未定义),常见的事情就是传递 3。 但是......如果它们在代码中使用超过 10 次只是为了缩小,那么传递更多是否有意义?

在我的例子中,我在代码中找到了全局变量 Math 14 次。将它传递给 IIFE 以节省 42 个字节是有意义的。在这种情况下并不是很多,但是如果我们一点一点地对不同的全局变量求和,那么传递尽可能多的全局变量总是有意义的,对吧? (符号、对象、错误、日期,JSON...)

(function($, window, document, Math, undefined) {
    $.fn.mydemo = function() {

    };
}(jQuery, window, document, Math));

那么,为什么这不是一种常见的方法?

更新:

解释42个字节的减少:

would it make sense to pass more if they are used more than 10 times in the code just for the fact of minification?

如果你那么关心缩小,当然,为什么不呢?

The common thing is just to pass 3 as far as I see everywhere (window, document and undefined)

Yes, altough you see not passing document, or passing jQuery (aliased as $), just as often. And of course it's not only about minification, but about performance,您只关心 windowdocument

it would always make sense to pass as many global variables as possible, right?

好吧,除非您不在代码中使用它们。 SymbolObjectErrorDateJSONMath等不需要 通常在大多数代码中。并且开发人员不喜欢每次更改一点代码时都执行您建议的那些字节数,因此此 IEFE 样板保持原样(恕我直言,它有很多货物崇拜)。

如果您真的很在意,您可以让您的缩小器自动执行此操作。

首先,这些值不是 IIFE。

这不是关于通过在函数内使用更短的变量名称来“节省字符”(至少不是主要),而是关于变量查找和与之相关的“成本”。

如果您要使用 f.e。 document 在你的函数中而不传入它,然后首先在函数范围内搜索名为 document 的变量,只有当失败时,搜索才会在其上方的范围内继续,依此类推上。

That 是将此类对象作为参数传递给函数的原因——以便 直接 在函数范围内引用它们存在,并且不必在更高的外部范围中查找它们。

有时,您甚至可能会看到它以这样的形式使用:

(function(document) {
  // do something with document, such as:
  document.foo();
  document.bar = "baz";
})(document);

– 那种形式,应该更清楚这不是在变量名中保存字符。该对象在函数内部仍被称为 document(这清楚地表明它应该代表什么——global document 对象),并且 only这样实现的效果据说是shorter lookup.

在很多情况下,将变量传递给 IIFE 是有意义的。

别名

将变量传递给 IIFE 允许您在函数内重命名变量。这在使用 jQuery 时很常见,尤其是在使用 noConflict 时:

(function ($) {
   //in here $ will be the same as jQuery
}(jQuery));

别名还有助于缩小器缩小代码,当您看到类似以下内容时:

(function (document, slice, Math) {
    ...
}(document, Array.prototype.slice, Math));

minifier 可以将参数重命名为任何它想要的名称,并节省您的字节数。对于大量使用这些属性的大型脚本,将其转换为:

可以节省大量资金
(function(a,b,c){...}(document,Array.prototype.slice,Math));

便携性

这更像是一种边缘情况,而不是一般规则,但通常会看到以下形式的全局 IIF:

(function (global /* or window */) {
    ...
}(this));

这允许 node.js 和浏览器之间的可移植性,以便全局变量在两种环境中具有相同的名称。

字符节省

虽然我已经提到缩小器可以通过更改别名来减少字符数,但如果您正在参加 code golf challenge,您可能希望手动执行此操作。

参考安全

如果您编写的脚本 必须 在其转储到的任何环境中工作(想想 google 分析),您需要确保您正在调用的全局方法是您所期望的。通过将它们作为参数传递来存储对这些函数的引用是防止对函数的引用被恶意或无知的程序员覆盖的一种方法。


回答标题中的问题:

How many globals make sense to be passed to the IIFE wrapper?

需要多少就多少,没有更多。如果您需要为一个或两个变量起别名,请传递一个或两个引用。如果您需要确保全局函数没有被更改,您可能会得到 100 个参数。对此没有 hard-and-fast 规则。