javascript 函数使用说明(2)

在前几篇文章已经介绍了函数要有返回值,即使没有写return,函数也会返回一个undefine。
接下来看看返回值为函数的情况
function a(){ 
alert('a'); 
return function(){ 
  alert('b'); 
}; 

在这个例子中,a函数执行了alert('a'),以及它返回了另一个函数b。关于返回b的调用我们可以这样来用。
var newFunc = a(); 
newFunc(); 
执行结果为 alert a和alert b
如果不想赋值调用这个函数也可以简写如下
a()(); 
函数的自身重写

因为函数可以返回一个函数,那就意味着可以用一个新的函数替代一个旧的函数,根据前一个例子来改进一下
a=a(); 
第一次运行函数a,就alert a,再次运行函数a,就alert b,这个功能对初始化非常有用。这个函数a重写了自己,避免在以后调用初始化的功能(上个例子为alert a)。
当然我们还有更简单的方法来重写a函数那就是在a函数的内部重写它,来看看代码
function a(){ 
alert("a") 
a=function(){ 
   alert("b"); 


只有在初次调用a函数才会执行 alert a 在以后的调用中,都会执行alert b
下面结合前几节看个综合的例子
var c = function(){ 
   function a(){ 
    alert('a') 
   } 
   function b(){ 
    alert('b') 
   } 
   a(); 
   return b; 
}();//alert('a'); 
c();//alert('b'); 
这个例子有以下几点需要注意
1. a函数,b函数是内部函数。
2. return b 返回的是个函数的引用。
3. 子调用函数重写了函数c。

如果能明白这个例子,关于内部函数,子调用函数和返回值为函数的函数就可以都理解了。

闭包(Closures)闭包属于比较难的一部分,在学习闭包之前,先来学习以下Javascript的作用域(Scope)

作用域链(Scope Chain)

函数内部定义的变量,在函数外不能访问,或者变量定义在代码段中(如if,for中),在代码段之外也不可访问。
var a =1; 
function f(){ 
var b=1; 
return a; 

f();//a=1 
b;//b 没有定义 
a 是全局变量,而b定义在函数f之中。所以:
在f函数中,a和b都可以访问。
在f函数之外,a可以访问,而b不可以

再次看个例子
var a = 1; 
function f(){ 
var b = 1; 
function n(){ 
  var c =3; 


如果定义一个函数n在函数f中,函数n不但可以访问自己作用域的c,而且还能访问所谓的父作用域的b和a
这就是作用域链(Scope Chain)
词法作用域(Lexical Scope)

在Javascript中,也有词法作用域(Lexical Scope),这个意思是,函数在定义的时候就生成了它的作用域,而不是在调用的时候,看个例子就明白了。
function f1(){var a=1;f2();} 
function f2(){return a;} 
f1();//a没有定义 
先看看函数f1,调用了函数f2,因为函数局部变量a也在f1中,可能期望函数f2也访问a,但事实却不是这样。
因为这个时候f2函数已经定义完毕了,而它的范围没有a被找到。不管是函数f1还是函数f2,仅仅能访问的是本身的局部变 量或者全局变量。

用闭包来破坏这个作用域链(Breaking the Chain with Closure)

让我们举例来说明闭包吧。
实例1

function f(){ 
var b="b"; 
return function(){ 
  return b; 


函数f包含了变量b,在全局作用域中不可能访问b,结果为没有定义(undefined)。
看看这个函数的返回值为一个函数。这个新的函数可以访问f范围中的变量b。看如下代码
var n = f(); 
n();//访问b 
由于函数f本身就是全局的,而它返回的函数又是个新的全局函数,而它又可以访问函数f的作用域。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wdszjy.html