zoukankan      html  css  js  c++  java
  • javascript 中的闭包

    理解必包三个基本事实

    1. JS允许你引用在当前函数以外定义的变量。

    ex:

    function makeSandwich(){

    var magicIngredient = “peanut butter”;

    function make(filling){

    return magicIngredient +’ and ‘+ filling;

    }

    return make(‘jelly’);

    }

    makeSandwich();

     

    2. 即使外部函数已经返回,当前函数仍然可以引用在外部函数所定义的变量。这意味着,你可以返回一个内部函数。

    ex:

    function mkSandwich(){

    var magicIngredient = ‘peanut butter’;

    function make (filling){

    return magicIngredient +’ and ‘+filling;

    }

    return make;

    }

    var mk =  mkSandwich();

    mk(‘jelly’);

    mk(‘bananas’);

    mk(‘marshmallows’);

     

    Javascript函数值在内部存储它们可能会引用的定义在其封闭作用域的变量。

    那些在其所涵盖的作用域内跟踪变量的函数被称为闭包。

    make函数就是一个闭包,引用两个外部变量: magicIngredient和filling。

    函数可以引用在其作用域内的任何变量,包括参数和外部函数变量。

    ex: 

    function mkSandwich(magicIngredient){

    function make(filling){

    return magicIngredient + ’and’ + filling;

    }

    return make;

    }

    var mk = mkSandwich(‘peanut butter’);

    mk(‘jelly’);

    mk(‘cheese’);

    var mkspeical = mkSandwich(’turkey’);

    mkspeical(’swiss’);

    mkspeical(‘provolone’);

     

    构建闭包的字面量语法-函数表达式

    ex:

    function mkSandwich(magicIngredient){

    return function(filling){

    return magicIngredient +’  and ‘+ filling;

    }

    }

     

    3. 必包可以更新外部变量的值。实际上必包存储的事外部变量的引用,而不是它们值的副本。

    ex:

    function box(){

    var val = undefined;

    return {

    set : function(newVal){

    val = newVal;

    },

    get : function(){

    return val;

    },

    type : function(){

    return typeof val;

    },

    }

    }

    var boxdemo = box();

    boxdemo.type();

    boxdemo.set(998);

    boxdemo.get();

    boxdemo.type();

     

     

    要搞清楚闭包,首先要知道javascript中的作用域.

     

    什么是作用域,你可以简单的理解成当前上下文环境.

     

    javascript 中的作用域有2种

    属于全局作用域.

    属于局部作用域

     

    全局作用域:

    比如我们在浏览器端编写的 javascript 代码,

    1

    var name=‘test’;

    我们直接定义了一个变量name ,那么这个变量当前作用域就是全局,对于浏览器端全局就是window

    更确切的说,name 是window 对象的一个属性.

    1

    2

    3

    console.log(window.name); //test

    console.log(name); //test

    console.log(this.name); //test

     

    上面三种输出方法,结果都是一样的,因为当前作用域就是window对象,this指向当前作用域.

     

     

    局部作用域:

    此类作用域是针对javascript中函数的作用域.

    是指在函数内部定义的变量,如下:

    1

    2

    3

    4

    function test(){

        var name=‘yijiebuyi’;

        alert(this.name);

    }

     

    上面 name 是一个局部变量,定义在函数内部,所以它的作用域就是此函数内部可以访问.

    alert(this.name);  this 指向当前作用域,因为在函数内部,所以指函数作用域.

     

    如果函数外部  alert(name); 将会报错,返回 undefined

    但是 函数内部可以访问函数外部作用域,如下:

    1

    2

    3

    4

    var name=‘test’;

    function test(){

       alert(name); //test

    }

    上面的代码没有问题,函数内部作用域可以访问全局作用域,(或者简单理解成 函数内部作用于可以访问它父级作用域)

     

    既然函数可以访问父作用域变量,而且函数是一等公民,可以当做参数,返回值等.

    那么问题来了:

    1

    2

    3

    4

    5

    6

    function test(){

        var name=‘yijiebuyi’;

        return function(){

            console.log(name);

        }

    }

    1

    2

    var rtn=test();

    rtn(); //yijiebuyi

    我们上面运行 rtn() ,得到 yijiebuyi,说明了2个问题:

    1.函数确实是头等公民,可以当参数,可以当返回值.

    2.函数可以访问它的父作用域,因为成功输出了 yijiebuyi

     

    我们再换一个思路:

    如果我不返回这个匿名函数,但是我想得到 test 函数中的 name 属性值,怎么办?

    好像不行,办不到,只能返回一个函数来获取 test 函数内部变量了,其实这个过程就是 一个典型的闭包!

     

    我们在返回匿名函数的时候并没有返回 var name=‘yijiebuyi’  但是运行 rtn 函数却得到了 name 属性值.

     

    所以:

    闭包的作用就是:把函数内部私有变量暴露出来. (暴露作用域)

    闭包如何实现:函数里面返回一个函数.

     

    这个返回函数自动带上了父函数所在的作用域,所以可以访问其内部变量,

    也正是因为闭包的存在,导致父函数执行完成后并没有被垃圾回收,它的作用域内的变量都将保存在内存中供闭包使用.

  • 相关阅读:
    hugeng007_SupportVectorMachine_demo
    hugeng007_RandomForestClassifier_demo
    hugeng007_pca_vs_Ida_demo
    hugeng007_Muti-Layer Perceptron_demo
    hugeng007_LogisticRegression_demo
    hugeng007_adaboost_demo
    渗透测试第三章web安全基础--web系统框架
    渗透测试第二章---网络协议安全
    渗透测试第一章 信息收集--- 扫描技术与抓包分析
    爬虫公开课学习的一天
  • 原文地址:https://www.cnblogs.com/papajia/p/4498218.html
Copyright © 2011-2022 走看看