关于前端:Javascript闭包

53次阅读

共计 1708 个字符,预计需要花费 5 分钟才能阅读完成。

每个函数在调用时,都会创立一个执行环境。这个执行环境有它的变量对象以及作用域链。通过作用域链,能够拜访下层的作用域的内容。

闭包的概念:

闭包是可能拜访另一个函数作用域中变量的函数(这个“另外一个函数”,通常指的是蕴含闭包函数的内部函数)

function outerFunction () {
var a = 1
return function () {console.log(a);
 }
}
 
var innerFunction = outerFunction();
innerFunction();

在这个例子里:负责打印 a 的匿名函数被包裹在内部函数 outerFunction 外面,且拜访了内部函数 outerFunction 作用域里的变量 a,所以从定义上说,它是一个闭包。

谈谈函数执行环境,作用域链以及变量对象(作用域和执行环境其实是同一个概念)

先援用一下《javaScript 高级语言程序》中的两段原话:

  1. “ 当某个函数被调用时,会创立一个执行环境(execution context)及相应的作用域链(scope Chain)” — —第 178 页 7.2 闭包
  2. “ 每个执行环境都有一个与之关联的变量对象(variable object),环境中定义的所有变量和函数都保留在这个对象中 ” — — 第 73 页 4.2 执行环境及其作用域

执行环境(execution context),作用域链(scope Chain)以及变量对象(variable object),但这三者们具体是什么关系呢?

汤姆大叔的文章中的伪代码:

ExecutionContext = {variableObject: { ....},
    this: thisValue,
    Scope: [ // Scope chain
      // 所有变量对象的列表
    ]
};

所以说,在函数调用的时候,会创立一个函数的执行环境,这个执行环境有一个与之对应的变量对象和作用域链。
每个函数的变量对象保留了它所领有的数据,以供函数外部拜访和调用,这些数据包含:(位于执行环境外部的)
1. 申明变量
2. 申明函数
3. 接管参数
例如:

function foo (arg) {
    var variable =’我是变量‘;
    function innerFoo () {alert("我是彭湖湾")
    }
}
foo('我是参数');

这个时候执行环境对应的变量对象就变成了这样:

ExecutionContext = {
    variableObject: {
      variable:’我是变量‘innerFoo:[对函数申明 innerFoo 的援用]
      arg: '我是参数'
    },
    this: thisValue,
    Scope: [ // Scope chain
      // 所有变量对象的列表
    ]
};

作用域链的作用:
通过作用域链,函数可能拜访来自它下层作用域(执行环境)中的变量
看个例子:

function foo () {
    var a = 1;
    function innerFoo () {console.log(a)
    }
    innerFoo();}
foo(); // 打印  1

作用域链其实就是个从以后函数的变量对象开始,从里到外取出所有变量对象,组成的一个列表。通过这个作用域链列表,就能够实现对下层作用域的拜访。

闭包与函数柯里化:
多层嵌套的闭包,这种用法,叫做“柯里化”。而闭包柯里化有两大作用:参数累加和提早调用

function foo (a) {return function (b) {return function (c) {console.log(a + b + c);
       }
     }
}foo('我')('叫')('彭湖湾'); // 打印 我叫彭湖湾

从这里,咱们能够很直观地看出 闭包柯里化的时候参数累加的作用
咱们把下面那个例子扭转一下:

function foo (a) {return function (b) {return function (c) {console.log(a + b + c);
       }
    }
}
 
var foo1 = foo('我');
var foo2 = foo1('叫');
foo2('彭湖湾'); // 打印 我叫彭湖湾

能够看到,最内层的闭包在外层函数 foo 和 foo1 调用的时候都没有调用,直到最初失去 foo2 并调用 foo2()的时候,这个最内层的闭包才失去执行,这也是闭包的一大个性——提早执行

https://www.cnblogs.com/pengh…

正文完
 0