前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JS中的闭包回顾

JS中的闭包回顾

作者头像
前端_AWhile
发布2019-08-29 13:14:46
1.3K0
发布2019-08-29 13:14:46
举报
文章被收录于专栏:前端一会前端一会

在弄明白函数闭包前,先要弄清楚函数执行时的上下文环境。

代码语言:javascript
复制
 1console.log(fn);
 2var fn = function(){    //函数表达未
 3    return 55;
 4}
 5//打印 undefined
 6
 7console.log(fn);
 8function fn(){      //函数声明
 9    return 55;
10}
11//打印
12/*
13ƒ fn(){
14        return 55;
15    }
16*/    

在全局环境下,由于有变量提升这个机制在,所以在执行上下文环境中,数据体现的不尽相同:

  • 变量、函数表达示 ———— 变量声明,默认赋值为 undefined
  • this ———— 赋值
  • 函数声明 ———— 赋值

而在函数体环境中,函数体内的arguments变量和函数的参数都已经被赋值,函数每次调用,都会创建一个新的上下文环境,因为不同的调用可能会有不同的参数。

代码语言:javascript
复制
1function fn(x){
2    console.log(arguments);     // [10]
3    console.log(x);             // 10
4}
5fn(10)

但是注意在函数定义(不是调用)的时候,就已经确定了函数体内部自由变量的作用域。

代码语言:javascript
复制
1var x = 22;
2function fn(){
3    console.log(x);     //x是自由变量,在函数fn创建时就确定了x要取值的作用域
4}
5function fn2(f){
6    var x = 50;
7    f();       //打印22,而不是50
8}
9fn2(fn)

给执行上下文环境下个通俗的定义:在执行代码前,把将要用到的所有变量都事先拿出来,有的直接赋值了,有的先用undefined占个空。

关于作用域,需要知道JS中没有块级作用域,此外还需要注意JS除了全局作用域外,只有函数可以创建局部作用域

作用域的概念比较抽象,可以理解为“地盘”,看下图:

上图所示,全局代码和fn、bar两个函数都会形成自己的作用域。而且,作用域有上下级关系,上下级关系的确定就看函数是在哪个作用域下确定的。例如,fn作用哉下创建了bar函数,那"fn作用域"就是"bar作用域"的上级。

作用域最大的作用就是隔离变量,不同作用域下同名变量不会有冲突。

这里再补充个自由变量的概念:在某个作用域中使用的变量X,却没有在该作用域中声明(换句话说就是变量X是在其他作用域中声明的),对于该作用域来说,这个变量X就是自由变量。那么这个自由变量X的取值又该怎么取呢?记住:要到创建这个函数的作用域中去取值,举例如下。

代码语言:javascript
复制
 1var x = 10;
 2function fn1(){
 3    console.log(x)
 4}
 5function fn2(f){
 6    var b = 20;
 7    (function(){
 8        f();    //打印10,而非20
 9    })()
10}
11fn2(fn1)

了解上下文环境和作用域,就可以比较顺畅的理解闭包了。闭包通常有两个应用场景:函数作为返回值、函数作为参数传递。

1、函数作为返回值:

代码语言:javascript
复制
 1function fn(){
 2    var max = 10;
 3    return function bar(x){
 4        if(x>max){
 5            console.log(x);     //20
 6        }
 7    }
 8}
 9var f1 = fn();
10f1(20)

上例中,闭包函数bar就是作为返回值。当执行到f1(20)时,在闭包函数bar中max作为自由变量是跨域取值的,还记得怎么跨域取值么?要到创建这个函数的作用域中去取

2、函数作为参数传递

代码语言:javascript
复制
 1var max = 10,
 2    fn = function(x){
 3        if(x > max){
 4            console.log(x);
 5        }
 6    };
 7
 8(function(f){
 9    var max = 100;
10    f(15);      //15
11})(fn);

上例中,函数fn就是作为参数传递到自执行匿名函数中去的,在执行f(15)时,作为参数传递进去的fn函数中的自由变量max取的值是10而非100,原因也是在于:自由变量的取值是要到创建这个自由变量所在函数的作用中去取的

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-12-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端小二 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档