关于函数

1. 函数声明和函数表达式有什么区别?

函数声明:function fn(){};
函数表达式:var fn=function(){};
区别: 1. 函数声明构造的函数要有函数名称。函数表达式可以是匿名函数。
      2. 函数声明可以变量提升,所以函数可以在声明前调用。而函数表达式不可以。(如图)
0_1481186355536_QQ截图20161208163900.jpg

2. 什么是变量的声明前置?什么是函数的声明前置?

  • 变量声明前置:所谓的变量声明前置就是在一个作用域块中,所有的变量都被放在块的开始出声明(如图)
0_1481187483634_QQ截图20161208165622.jpg
  • 函数声明前置:对于函数声明,js解析器会优先读取,确保在所有代码执行之前声明已经被解析,而函数表达式,如同定义其它基本类型的变量一样,只在执行到某一句时也会对其进行解析。(如图)
0_1481188766228_QQ截图20161208171809.jpg
0_1481188782999_QQ截图20161208171908.jpg

3. arguments 是什么?

  • arguments不能够创建,是函数自身的参数,只有当函数开始执行是才能使用
    虽然arguments的使用方法,很像数组,但是它并不是数组。
0_1481192600569_QQ截图20161208182306.jpg
0_1481193644321_QQ截图20161208184030.jpg

4 .函数的重载怎样实现

    JS的函数定义可以指定形式参数名称,多多少少我们会以为js至少可以支持参数个数不同的方法重载,然而遗憾的是这仅仅是一个假象,js所有的参数都是以arguments传递过去的,这个参数类似于数组,在函数调用的时候,所有的实参都是保存在了这个数据结构里面,我们定义函数的时候所指定的形式参数其实是为这个数据结构里面的数据定义一个快捷的访问方式。也就是说js所有的函数都是支持无限个参数的,加上数据类型是弱类型,那么JS的函数除了名称就真的没有方法区别了?
  办法总是有的,我们可以利用JavaScript中的特殊对象arguments来模拟函数重载。用它来判断传入参数的个数或类型以区分

0_1481203159145_QQ截图20161208211906.jpg

5. 立即执行函数表达式是什么?有什么作用?

  • 执行函数表达式是什么
(function(){alert(‘我是匿名函数’)}()); // 用括号把整个表达式包起来
(function(){alert(‘我是匿名函数’)})(); //用括号把函数包起来
  • 作用:
一是不必为函数命名,避免了污染全局变量;
二是函数内部形成了一个单独的作用域,可以封装一些外部无法读取的私有变量。

6. 什么是函数的作用域链

   作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。
在JavaScript中,变量的作用域有全局作用域和局部作用域两种。
在代码中任何地方都能访问到的对象拥有全局作用域
局部作用域一般只在固定的代码片段内可访问到,最常见的例如函数内部,所有在一些地方也会看到有人把这种作用域称为函数作用域
   在JavaScript中,函数也是对象,实际上,JavaScript里一切都是对象。函数对象和其它对象一样,拥有可以通过代码访问的属性和一系列仅供JavaScript引擎访问的内部属性。其中一个内部属性是[[Scope]],由ECMA-262标准第三版定义,该内部属性包含了函数被创建的作用域中对象的集合,这个集合被称为函数的作用域链,它决定了哪些数据能被函数访问。
  • 举例:


    0_1481213643993_QQ截图20161209001349.jpg

1.分析原因:
第一步:首先定义了一个全局变量a,并且将1赋值给这个a;
第二步:然后建立了一个函数fn(),在函数fn里面定义了局部变量b,并且赋值2给b;
第三步:求fn2()的值,并且定义了fn2()函数,里面是console.log(a)和console.log(c);
第四步:在函数fn中定义了局部变量c并赋值3给c;
第五步:求函数fn();
那么,在这中间发生了什么呢?
1.变量提升,全局变量a的声明提升到最上面变成var = a;a = 1;
2.函数fn()中的局部变量b和c的变量提升到fn()的最上面变成var b;var c;
3.然后函数fn2提升到var b;var c;的下面,后面接着就是求fn2();
4.变量的赋值在函数fn()的最底下:b = 2; c = 3;
5.求fn()的值,也就是fn2()的值;
6.执行的顺序是从上到下的,整个函数变成了如下代码


0_1481214026690_QQ截图20161209002001.jpg

这个函数中的作用域链是这样的:
1.从上诉可知这个函数的作用域有三个,互成链条,分别是(从外到内)①:全局作用域;②:fn()作用域;③:fn2()作用域
2.执行函数fn2()后,首先在函数fn2()中console.log(a),fn2()就在自身域中找a,没有找到就到上面一层也就是fn()中找a,也没有找到,于是就到全局变量中找a,得到a已经被声明,并且值为1,所以得到a为1;
3.然后fn2()中console.log(c),c在fn2()作用域中也没有找到,就到上一层fn()作用域中找c,而c此时已经被声明但是并未赋值,所以console.log(c)会得到undefined;
4.执行完函数fn2()得出结果后,fn2()被销毁,得出的值变为fn()的值;
上面所诉的就是一个函数的作用域链,总结来说就是,某个函数寻求变量的时候,在自身作用域中找不到就会到上一层作用域去找,一直到全局变量为止,这一个个的作用域连接起来就是作用域链;

代码练习

1. 以下代码输出什么?

0_1481205029245_QQ截图20161208215013.jpg
1、在函数体内部可以通过arguments对象来访问传递给函数的每一个参数。
2、函数不介意传递进来多少个参数,也不在乎传进来的参数是什么类型,如果没有传递值的命名参数将自动被赋予undefined值。
3、arguments的值永远与对应命名的参数的值保持同步。

2. 写一个函数,返回参数的平方和?

0_1481207104289_QQ截图20161208222451.jpg

3 .如下代码的输出?为什么 ?

0_1481207206203_QQ截图20161208222634.jpg
变量提升:
var a;
console.log(a);
a=1;
console.log(b);
a被声明但没有赋值所以第一个undefined;
b没有被声明报错;

4. 如下代码的输出?为什么

0_1481207506909_QQ截图20161208223136.jpg
sayName函数声明,跟变量声明提前一样,也会进行函数声明前置。所以sayName的函数打印结果为hello world
saAge是函数表达式,不会进行声明提前,所以当调用表达式在函数表达式前面会报错提示sayAge is not a function ,如果调试表达式在函数表达式后面。就能正常使用。

5. 如下代码的输出?为什么

0_1481207732443_QQ截图20161208223523.jpg
当在同一个作用域内定义了名字相同的变量和方法的话,无论其顺序如何,变量的赋值会覆盖方法的赋值.

6. 如下代码的输出?为什么

0_1481210060453_QQ截图20161208231200.jpg
0_1481210150115_QQ截图20161208231538.jpg

7. 如下代码的输出?为什么?

0_1481210407807_QQ截图20161208231949.jpg
输出结果是错误,fn不是一个函数
原因:fn被声明并被赋值为1,此时的fn不是一个函数,而console.log(fn(fn))是输出这个fn这个函数,所以发生冲突;

8 .如下代码的输出?为什么?
0_1481210792302_QQ截图20161208232404.jpg

0_1481210929683_QQ截图20161208232841.jpg

9. 如下代码的输出?为什么

0_1481212564162_QQ截图20161208234107.jpg
0_1481212586960_QQ截图20161208235557.jpg

10. 如下代码的输出?为什么

0_1481213251035_QQ截图20161209000147.jpg
0_1481213260572_QQ截图20161209000415.jpg

版权归饥人谷--楠柒所有如有转发请标明出处谢谢

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

推荐阅读更多精彩内容