【阅文笔记】函数作用域【你不知道的JavaScript(上)】

函数作用域

一、函数作用域

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

看下面代码:

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 的语法中这是非法的

匿名函数表达式有如下缺点:

  1. 没有意义的名称,调试困难
  2. 当函数需要引用自身时,麻烦
  3. 代码可读性/可理解性差

给函数表达式指定一个函数名可以有效解决以上问题。 始终给函数表达式命名(具名函数表达式)是一个最佳实践
在这里插入图片描述

三、立即执行函数表达式
var a = 2;

(function foo() {
var a = 3;
console.log( a ); // 3
})();

console.log( a ); // 2

由于函数被包含在一对 ( ) 括号内部, 因此成为了一个表达式, 通过在末尾加上另外一个( ) 可以立即执行这个函数, 比如 (function foo(){ … })()。 第一个 ( ) 将函数变成表达式, 第二个 ( ) 执行了这个函数

这叫IIFE👉立即执行函数表达式

IIFE 最常见的用法是使用一个匿名函数表达式。 虽然使用具名函数的 IIFE 并不常见, 但它具有上述匿名函数表达式的所有优势, 因此也是一个值得推广的实践(通过匿名函数表达式缺点得出)

在这里插入图片描述
相较于传统的 IIFE 形式, 很多人都更喜欢另一个改进的形式: (function(){ .. }())

这两种形式在功能上是一致的,随意选择

IIFE另一个非常普遍的进阶用法是把它们当作函数调用并传递参数进去(第二段代码👇)
在这里插入图片描述
我们将 window 对象的引用传递进去, 并将参数命名为 global

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值