JavaScript函数作用域

我们已经知道,在任意代码片段外部添加包装函数,可以将内部的变量和函数定义“隐藏”起来,外部作用域无法访问包装函数内部的任何内容。

例如:

var a=2;

function foo(){

   var a=3;

   console.log(a);

}

foo();

console.log(a);

虽然这种技术可以解决一些问题,但是它并不理想,因为会导致一些额外的问题。首先,必须声明一个具名函数foo(),意味着foo这个名称本身“污染”了所在的作用域(在这个例子中是全局作用域)。其次,必须显示地通过函数名foo()调用这个函数才能运行其中的代码

如果函数不需要函数名(或者至少函数名可以不污染所在作用域),并且能够自动运行,这将会更加理想。


JavaScript提供了能够同时解决这两个问题的方案:

(function foo(){

           var a=3;

          console.log(a);

})();

console.log(a);

接下来分别介绍这里发生的事情


首先,包装函数的声明以(function...而不是function....开始。尽管看上去这并不是一个很显眼的细节,但实际上却是非常重要的区别。函数会被当作函数表达式而不是一个标准的函数声明来处理

注:区分函数声明和表达式最简单的方法是看function关键字出现在声明中的位置(不仅仅是一行代码,而且是整个声明中的位置)。如果function是声明中的第一个词,那么就是一个函数声明,否则就是一个函数表达式。


函数声明和函数表达式之间最重要的区别是它们的名称标识符会绑定在何处。

 

比较一下前面两个代码片段。第一个片段中foo被绑定在作用域中,可以直接通过foo()来调用它。第二个片段中foo被绑定在函数表达式自身的函数中而不是所在作用域中。


换句话说,(function fun(){...})作为函数表达式意味着foo只能在....所代表的位置中被访问外部作用域则不行。foo变量名被隐藏在自身中意味着不会污染外部作用域。

你可能感兴趣的:(JavaScript,js,函数作用域,函数声明,函数表达式)