命名闭包会污染全局/窗口对象吗?

时间:2012-09-18 15:13:49

标签: javascript node.js coding-style v8

根据this node style guide,给闭包一个名字是一个好习惯:

  

从右

req.on('end', function onEnd() {
  console.log('winning');
});
     

错误

req.on('end', function() {
  console.log('losing');
});

然而,我习惯于想到

function someName() { someStatements(); }

...语法为该函数创建全局变量someNamewindow.someName。这真的是一个很好的做法,还是一个非常糟糕的风格指南?

4 个答案:

答案 0 :(得分:4)

虽然节点不会出现此问题:

命名函数表达式在Internet Explorer中出现错误,并将污染窗口对象,如下所述:http://kangax.github.com/nfe/ 在“JScript错误”下

(不是那么)有趣的是,即使在从未执行过的条件块中也会创建它们,如下例所示:

var f = function g() {
  return 1;
};
if (false) {
  f = function g(){
    return 2;
  };
}
g(); // 2

这在我使用的生产网站上造成了一个问题,其中jQuery突然被其他东西取代(https://dev.plone.org/ticket/12583

答案 1 :(得分:3)

在node.js中,您描述的内容不会污染全局上下文

假设:

function someName() { someStatements(); }

global.someName将被定义。以下是:

setTimeout(function someName() { someStatements(); }, 500);

设置global.someName

这似乎只是一个美学问题。我使用node.js v0.8.4对此进行了测试,但在大多数现代浏览器中都应该存在相同的行为。

答案 2 :(得分:1)

命名闭包的名称只能在此闭包的内部中访问,因此它不应该污染全局命名空间。 通常,您将使用命名闭包来创建递归闭包。

答案 3 :(得分:0)

您无法使用名称访问匿名函数(如果函数具有名称)。它可以在功能体内访问。所以它不会污染窗口对象。

req.on('end', function onEnd() { 
  console.log(onEnd); //function body
}); 
console.log(onEnd); //ReferenceError: onEnd is not defined