我已经在JavaScript方面工作了一段时间,通常会做类似于这样的事情,只是为了缓存深层结构或“命名空间”内声明的函数属性的值。
//global scope
(function ($, lib) {
//function scope 1
var format = lib.format, // instead of calling lib.format all the time just call format
touch = lib.pointer.touch, //instead of calling lib.pointer.touch each time just touch
$doc = $(document),
log = logger.log; //not console log...
$doc.on('app:ready', function () {
//function scope 2
$doc.on('some:event', function (e) {
//function scope 3
//use the cached variables
log(format('{0} was triggered on the $doc object', e.type);
});
$doc.on(touch, function (e) {
//function scope 3
log(format('this should be {1} and is... {0} ', e.type, touch);
});
});
}(jQuery, lib));
我这样做是因为:
- 即使在功能强大、带有花哨自动完成的 IDE 可以帮助,写 touch 似乎比写 lib.pointer.touch 更吸引人,因为我很懒。
- 一个最小化器可以将单个私有变量转换为单个字母变量,所以对我来说也有意义(我知道,我知道,不要过早优化,但我想这似乎是安全的)。
所有以这种方式编写的代码似乎在移动设备和桌面浏览器上表现良好,所以它似乎是一种安全的实践(在“实践”中,双关语)。但由于这依赖于闭包,而内部函数必须创建一个闭包来保存它声明时的上下文,所以我在想...
if a function does not uses variables from the outside context (free variables)... is the closure context still saved? (or if i a tree falls in the wood and nobody is there to hear it, does it still make the crash sound? hehe) I'm aware that this could vary between javascript engines, because ECMA mention nothing about if it is required to save the context or not when variables from the outside are not accessed.
if the above expression is true... will this block of code be more efficient?
//global scope (function ($, lib) { //function scope 1 var format = lib.format, touch = lib.pointer.touch, $doc = $(document), log = console.log; $doc.on('app:ready', function () { (function ($doc, touch, lib, format) { // since all the variables are provided as arguments in this function // there is no need to save them to the [[scope]] of this function // because they are local to this self invoking function now $doc.on('some:event', function (e) { //function scope 3 //use the cached variables log(format('{0} was triggered on the $doc object', e.type); }); $doc.on(touch, function (e) { //function scope 3 log(format('this should be {1} and is... {0} ', e.type, touch); }); }($doc, touch, lib, format)); }); }(jQuery, lib));
将这些变量传递给立即调用的函数是更有效的吗?创建新函数的成本是否会对代码产生任何影响(负面或积极)?
我如何以可靠的方式正确测量我的JavaScript库的内存消耗?我有 100x 小型 JavaScript 模块,都在立即自执行函数内部,大多数情况下是为了避免变量泄漏到全局上下文中。因此,它们都被包装在非常类似于上面提到的代码块的模块中。
即使这意味着我必须在更接近将要使用它们的地方重复变量声明,将变量缓存得更近是否会产生更好的效果?
我有一种感觉,在当前本地上下文中找不到变量时,引擎将首先查找父级作用域并迭代该级别的所有变量...每个级别的变量越多,查找变量的性能可能就越差。
从内部闭包中尝试查找未定义的变量将是最昂贵的,因为根据定义,将首先在父级范围中搜索变量,直到全局范围,并且找不到它将迫使引擎最终到达全局范围。这是真的吗?引擎是否优化了这种查找?
根据这个测试... 似乎第二种方法更快。但只有在迭代大量次数时才明显...现在我的代码没有执行那么多次迭代...但可能因为我的编码方式而消耗了更多的内存...
更新:有人指出这个问题太大了。很抱歉,我会尝试分成小部分。正如我所说,这个问题主要是出于好奇心,即使在移动设备上性能也几乎可以忽略不计。谢谢你们的反馈。
$doc = $doc
是为了优化将全局变量引入到本地作用域中? - Ruan Mendes