JS函数简介(二)----函数作用域、函数作用域链、函数的递归

一、函数的作用域

首先,作用域就是指变量的作用范围
然后,在JS中只有两个作用域:1.全局作用域,2.局部作用域(函数作用域)

  • 全局作用域

    • 简介:
      全局作用域就是函数作用域外的作用域,处于window对象之中;
    • 全局变量:
      1.全局变量是指不在函数内部创建的变量,全局变量都处于window对象之中,如下变量就是在一个全局变量:


      全局变量

      2.另外,在函数内部创建变量时,如果不加var进行声明,那么这个变量也是全局变量,


      不加var声明的变量都是全局变量
  • 局部作用域(函数作用域)

    • 简介:
      局部作用域是指在创建了函数后,在函数内部形成的作用域;
    • 局部变量:
      1.局部变量是指在函数内部通过var进行声明的变量,如下变量就是一个局部变量:


      局部变量
  • 全局变量和局部变量的调用

    • 在函数中,如果函数需要传入一个变量,而这个变量并不在它自身内部,那么就可以调用全局下的变量:


      函数调用全局变量
    • 全局作用域下不能调用函数内的局部变量


      提示错误变量a没有声明
    • 那么如何在全局作用域下对局部变量进行调用呢?有两个办法:1、函数return这个变量再赋值;2、使用闭包;
      1.函数return这个变量,再将return的值赋值给一个全局变量:


      把变量return后赋值

      2.使用闭包,在函数内部再创建一个函数,返回这个函数:


      使用闭包
  • 关于关键词var的两点
    • 在全局作用域下的函数中不加var对变量进行声明时,就是全局变量:


      不加var进行声明的变量都是全局变量
    • 在同一个作用域内,当一个变量已经被声明并被赋值,后面再次对其进行声明,该变量的值不变:


      重复声明值不变

二、关于函数的作用域链

  • 简介
    1.函数的作用域链就是指函数在调用变量时所经过的路径,比如函数fn调用变量a,但是它自身并没有变量a(没有在函数内部用var进行声明),于是就从全局作用域下找变量a,找到就调用全局变量a,那么这个过程就是函数fn的作用域链;
    2.要了解函数作用域链,首先就要知道在函数对象中,拥有一个内部属性[[Scope]],该内部属性包含了函数被创建的作用域中对象的集合,这个集合被称为函数的作用域链,它决定了哪些数据能被函数访问。
    3.简单来说:函数对变量的调用是由自身开始向外一层一层找的,距离自身最近变量被找到,就调用该变量;

  • 画出函数的作用域链
    1.代码如下:


    2.首先因为变量提升和声明前置,我们将代码修改成下面这样:
    变量提升和声明前置

    3.第一步找到全局作用域下,发现有全局变量i和全局变量fn,然后全局变量fn变成了一个函数,于是可以写出如下伪代码:

    全局作用域下

    4.找到函数fn作用域下,发现有局部变量i和函数fn2,但是因为没有执行,所以这两项并未被创建,又因为函数fn处于全局作用域下,所以它也可以对全局作用域下的变量进行调用,所以fn的[[Scope]]包含全局作用域globalScope

    fn作用域下

    5.然后在函数fn中有一个函数fn2,发现它里面没有自身的局部变量,但是因为fn2是在函数fn内被声明,所以fn2的[[Scope]]包含fn的作用域fnScope,并且fn2也可以对全局作用域下的变量进行调用,所以也包含全局作用域globalScope(全局作用域);
    fn2作用域下

    6.执行函数fn,进入了fn的执行上下文中fn execution context,此时声明了变量i以及函数fn2,i此时未被赋值,所以是i的值是undefined:


    7.因为i的值是undefined,所以console.log(i)得到的就是undefined,所以执行fn得到的第一个结果就是undefined,然后将99赋值给了i,i变为99


    8.然后执行fn2,进入到fn2的执行上下文fn2 execution context,fn2将100赋值给i,但是因为它自身没有变量i,于是先到上一层,也就是函数fn中找变量i,得到fn中的i后进行赋值,函数fn中的i变为了100,所以下面的console.log(i)得到的值就是100,函数fn执行的第二个结果就是100;


    9.执行完函数fn后,进入到全局作用域的执行上下文global execution context中,将10赋值给全局变量i,20赋值给全局变量fn,然后因为下面的console.log(i)是在全局作用域下执行,所以这里的i是全局变量的i,得到最后一个结果10;


    10.所以这段代码的执行结果依次为undefined、100、10,而以上这个一层一层向上找变量的过程就是作用域链;
    结果

三、函数递归

  • 什么是递归
    递归简单说来就是不断地重复执行同样的代码来解决问题
  • 函数的递归
    1.特点:
    ①:自己调用自己;
    ②:要设定终止条件;
    2.优缺点
    ①:算法简单;
    ②:效率低;
  • 一个使用递归的简单例子,求n的阶乘n!
    比如求5的阶乘就是5! = 5*4*3*2*1
    由此可知,n的阶乘就是n! = n*(n-1)*(n-2)....
    (n-2) = (n - 1) - 1
    由此可知代码如下:
    求阶乘

    输出结果:
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容

  • 函数声明和函数表达式有什么区别 (*)解析器会率先读取函数声明,并使其在执行任何代码之前可以访问;函数表达式则必须...
    coolheadedY阅读 382评论 0 1
  • 1.函数声明和函数表达式有什么区别 (*) 区别: 函数声明后面的分号可加可不加,不加也不影响接下来语句的执行,但...
    Sheldon_Yee阅读 388评论 0 1
  • 1.函数声明和函数表达式有什么区别 (*) 函数声明 函数表达式 函数声明:函数调用可以发生在函数声明之前,例如下...
    TimeLesser阅读 384评论 4 4
  • 2015.11.03 星期二 广州 晴 今天上午外出拜访了商工会里的一家日本企业,到了工厂后,看到工厂外面大门紧锁...
    邱比货代君阅读 297评论 1 0
  • 感谢那些幸福的事情,让我们知道亲情,爱情的可贵,让我们知道要学会珍惜 同事也要感谢生活中不开心的小事,让我们知道很...
    倾斜5度阅读 238评论 0 1