程序员@IT·互联网

JavaScript函数式编程-闭包(四)

2016-08-10  本文已影响96人  陈7号

什么是闭包
闭包就是能够读取其他函数内部变量的函数,由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。
闭包是一种特殊的对象。它由两部分构成:函数,以及创建该函数的环境。
环境由闭包创建时在作用域中的任何局部变量组成

闭包的意义

  1. 闭包允许将函数与其所操作的某些数据(环境)关联起来
  2. 可以用闭包模拟私有方法

注意
如果不是因为某些特殊任务而需要闭包,在没有必要的情况下,在其它函数中创建函数是不明智的,因为闭包对脚本性能具有负面影响,包括处理速度和内存消耗。

看了很多闭包相关的资料,还是不知道怎么把闭包讲清楚,大概是自己的能力还有限,就先把看到的一些例子放进来,有时候可能看代码更容易理解一点,待我某天开窍了,好好写一写

示例

例一

function sayHello(name) {
    var text = 'Hello ' + name;
    var say = function() { console.log(text); }
    say();
}

例二

function sayHello2(name) {
    var text = 'Hello ' + name; // 局部变量
    var say = function() { console.log(text); }
    return say;
}
var say2 = sayHello2('Bob');
say2(); // 输出 "Hello Bob"

例三

function say667() {
    // Local variable that ends up within closure
    var num = 42;
    var say = function() { console.log(num); }
    num++;
    return say;
}
var sayNumber = say667();
sayNumber(); // logs 43

例四

var gLogNumber, gIncreaseNumber, gSetNumber;
function setupSomeGlobals() {
    // Local variable that ends up within closure
    var num = 42;
    // Store some references to functions as global variables
    gLogNumber = function() { console.log(num); }
    gIncreaseNumber = function() { num++; }
    gSetNumber = function(x) { num = x; }
}

setupSomeGlobals();
gIncreaseNumber();
gLogNumber(); // 43
gSetNumber(5);
gLogNumber(); // 5

var oldLog = gLogNumber;

setupSomeGlobals();
gLogNumber(); // 42

oldLog() // 5

例五

function buildList(list) {
    var result = [];
    for (var i = 0; i < list.length; i++) {
        var item = 'item' + i;
        result.push( function() {console.log(item + ' ' + list[i])} );
    }
    return result;
}

function testList() {
    var fnlist = buildList([1,2,3]);
    // Using j only to help prevent confusion -- could use i.
    for (var j = 0; j < fnlist.length; j++) {
        fnlist[j]();
    }
}

 testList() //logs "item2 undefined" 3 times

例六

function sayAlice() {
   var say = function() { console.log(alice); }
   // Local variable that ends up within closure
   var alice = 'Hello Alice';
   return say;
}
sayAlice()();// logs "Hello Alice"

例七

function newClosure(someNum, someRef) {
    // Local variables that end up within closure
    var num = someNum;
    var anArray = [1,2,3];
    var ref = someRef;
    return function(x) {
        num += x;
        anArray.push(num);
        console.log('num: ' + num +
            '\nanArray ' + anArray.toString() +
            '\nref.someVar ' + ref.someVar);
      }
}
obj = {someVar: 4};
fn1 = newClosure(4, obj);
fn2 = newClosure(5, obj);
fn1(1); // num: 5; anArray: 1,2,3,5; ref.someVar: 4;
fn2(1); // num: 6; anArray: 1,2,3,6; ref.someVar: 4;
obj.someVar++;
fn1(2); // num: 7; anArray: 1,2,3,5,7; ref.someVar: 5;
fn2(2); // num: 8; anArray: 1,2,3,6,8; ref.someVar: 5;

在前端摸爬滚打中,欢迎指正

上一篇 下一篇

猜你喜欢

热点阅读