IIFE可以用来避免名称冲突?

时间:2019-01-09 01:26:03

标签: javascript

(function(){
  var a = b = 3;
})();

(function(){
  var a = b = 5;
})();


console.log(b)
console.log(a)

IIFE有助于避免名称与其他模块冲突?我已经尝试了上面的代码来理解这个概念。基本上,我可以假定上面的两个IIFE代表两个不同的“模块”,并且变量b不应被覆盖吗?但是,我们可以知道b的值被改写为5。

另一个问题是,为什么在上述情况下未定义变量a? 我以为基本上代码会被翻译成下面的

var a = b = 3;

let b = 3;
let a = b;

3 个答案:

答案 0 :(得分:3)

正因为如此,

var a = b = 3;是一个反模式。执行此操作时,b永远不会用var声明。等效于:

b = 3         // no var makes b global 
var a = b;    // var a is scoped to enclosing function

这会将b放在全局名称空间中,这可能不是您想要的。

function test(){
  var a = b = 3;  // b 'looks' like it will be function scoped...but
}

test()
console.log(b) // b is global even though defined in the function

答案 1 :(得分:2)

var a = b = 3;

首先考虑

b = 3

3分配给(隐式全局)变量“ b”。该赋值表达式的值为3,所以

var a = b = 3;

然后变成

var a = 3;

var之前的a意味着变量名称a仅在包含函数内定义-它不会泄漏到全局变量中范围。你曾经用过

a = b = 3;

然后,像ba一样也将隐式分配给全局对象。

您可能要确保每个IIFE对b都有单独的绑定,可以通过首先用b声明var来完成:

(function(){
  var b;
  var a = b = 3;
})();

(function(){
  var b;
  var a = b = 5;
})();
// neither a nor b are defined here

console.log(b)
console.log(a)

在使用变量之前最好总是用var(或者更好的是constlet)声明变量名。

在可能的情况下,最好避免将赋值评估为表达式,因为它看起来很混乱:

(function(){
  var b = 3;
  var a = b;
})();

(function(){
  var b = 3;
  var a = b;
})();
// neither a nor b are defined here

console.log(b)
console.log(a)

答案 2 :(得分:0)

在没有var的情况下分配变量会创建“自动全局变量” 这就是为什么a未定义但b不是的原因