闭包是如何工作的?

简单来说,闭包(closure)是函数在声明时访问函数自身之外的变量时所创建的作用域

让我们将这句话分解来看:一、闭包是作用域,二、函数在声明时访问外部变量所创建的作用域。另外:声明的函数在后续的任何时刻都可以被调用,即使是声明时的作用域消失之后。

从最简单的代码开始理解:

在这个最简单的例子中,outerFunction能够访问到外部的outerValue变量。这样的代码,我们可能已经编写了成千上万次,但是却没有意识到其实我们已经创建了一个闭包。

一点都不特别是吧?因为外部变量与外部函数都是在全局作用域内声明的,该作用域(也是闭包)从未消失过(因为页面已经被加载)。所以该函数可以访问到外部变量也就不足为奇了,因为它仍在作用域内并且是可用的。这种情况下,即使有闭包的存在,我们也不清楚他的好处。

查看全文

利用参数个数以及闭包进行函数重载

基于传入的参数,有很多种方法可以判断并进行函数重载。一种通用的方法是,根据传入参数的类型执行不同的操作;另一种方法是,可以通过判断某些特定的参数是否存在来执行不同的操作;还有一种方法是判断传入参数的个数来执行不同的操作。本文介绍的就是最后一种方法。

对于一个函数,在参数方面,我们可以确定两件事情:

  • 通过函数的length属性,可以知道声明了多少命名参数(形参个数)
  • 通过arguments.length,可以知道在调用时传入了多少参数(实参个数)

查看全文

JavaScript 中作用域与函数

在 JavaScript 中,作用域由函数决定( fucntion scope,lexical scope ),不是代码块( block scope )。

当我们声明一个函数时,我们不仅要关注该函数可用的作用域,还要关注该函数自身所创建的作用域,以及函数内部的声明是如何影响这些作用域的

JavaScript 的作用域行为,与受 C 语言语法影响的作用域不太一样,也就是那些使用括号({ })作为分隔符的语言。在大多数这样的语言中,每一个代码块都会创建自己的作用域,但在 JavaScript 中却并非如此!

在 JavaScript 中,作用域是由函数声明的,而不是代码块。声明的作用域创建于代码块,但不是终结于代码块,比如下面的代码:

name的作用域开始于var标记处,但却不是结束于大括号,而是结束于所在函数的结尾

查看全文

JavaScript 的作用域链浅析

JavaScript 是基于词法作用域的语言:通过阅读包含变量定义在内的数行源代码就能知道变量的作用域。

一些类 C 的语言是使用块级作用域(block scope),花括号内的第一段代码都具有各自的作用域,而且变量在声明它们的代码之外是不可见的。

而 JavaScript 中没有块级作用域,取而代之地使用了函数作用域(function scope),即词法作用域:变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义。词法作用域意味着变量在声明之前甚至已经可用,JavaScript的这个特性被非正式地称为声明提前(hoisting),如下代码:

继续阅读