在任意代码片段外部添加包装函数,可以将内部的变量和函数定义“隐 藏”起来,外部作用域无法访问包装函数内部的任何内容。 例如:
var a = 2;
function foo() { // <-- 添加这一行
var a = 3; console.log( a ); // 3
} // <-- 以及这一行 foo(); // <-- 以及这一行
console.log( a ); // 2
虽然这种技术可以解决一些问题,但是它并不理想,因为会导致一些额外的问题。首先, 必须声明一个具名函数 foo(),意味着 foo 这个名称本身“污染”了所在作用域(在这个 例子中是全局作用域)。其次,必须显式地通过函数名(foo())调用这个函数才能运行其 中的代码。 如果函数不需要函数名(或者至少函数名可以不污染所在作用域),并且能够自动运行, 这将会更加理想。 幸好,JavaScript 提供了能够同时解决这两个问题的方案、
var a = 2;
(function foo(){ // <-- 添加这一行 var a = 3;
console.log( a ); // 3 })(); // <-- 以及这一行 console.log( a ); // 2
接下来我们分别介绍这里发生的事情。 首先,包装函数的声明以 (function... 而不仅是以 function... 开始。尽管看上去这并不 是一个很显眼的细节,但实际上却是非常重要的区别。函数会被当作函数表达式而不是一 个标准的函数声明来处理。 区分函数声明和表达式最简单的方法是看 function 关键字出现在声明中的位 置(不仅仅是一行代码,而是整个声明中的位置)。如果 function 是声明中 的第一个词,那么就是一个函数声明,否则就是一个函数表达式。 函数声明和函数表达式之间最重要的区别是它们的名称标识符将会绑定在何处。 比较一下前面两个代码片段。第一个片段中 foo 被绑定在所在作用域中,可以直接通过 foo() 来调用它。第二个片段中 foo 被绑定在函数表达式自身的函数中而不是所在作用域中。 换句话说,(function foo(){ .. })作为函数表达式意味着foo只能在..所代表的位置中 被访问,外部作用域则不行。foo 变量名被隐藏在自身中意味着不会非必要地污染外部作 用域。
匿名和具名 对于函数表达式你最熟悉的场景可能就是回调参数了,比如:
setTimeout( function() {
console.log("I waited 1 second!");
}, 1000 );
这叫作匿名函数表达式,因为 function().. 没有名称标识符。函数表达式可以是匿名的, 而函数声明则不可以省略函数名——在 JavaScript 的语法中这是非法的。 匿名函数表达式书写起来简单快捷,很多库和工具也倾向鼓励使用这种风格的代码。
标签:function,函数,作用域,js,foo,声明,表达式 From: https://blog.51cto.com/u_16273048/9355711