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

什么是闭包
闭包就是能够读取其他函数内部变量的函数,由于在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;

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 定义函数的方式有两种:函数声明和函数表达式。 函数声明的一个重要特征就是函数声明提升,意思是在执行代码前会先读取函...
    oWSQo阅读 687评论 0 0
  • 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。 一、变量...
    zock阅读 1,085评论 2 6
  • 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。 一、变量...
    zouCode阅读 1,287评论 0 13
  • 燃半卷烟,消磨着美好的旧时光,风一吹,倒戈了万千风情的影子,眉眼间的忧郁沧桑,消散了,绝非灰飞烟灭,而是揉在风...
    影半月半阅读 918评论 0 5
  • 大家好,第33次语音60秒。 Toastmaster是一个非盈利组织,主要是帮助人演讲。 他的活动分5个阶段: 1...
    bluealon阅读 607评论 0 1