c函数引用全局变量出错undefined reference_js函数与作用域

看完这篇文章,你将了解:

1.js 函数的五种声明方式

2.js 函数的本质

3.this 和 arguments 是什么

4.树与作用域

5.其他小知识


一、函数的5种声明方式

1:具名函数

function f(x,y){ }

2:匿名函数

var f = function (x,y){ }

3:

var f = function z(x,y){ }
注:这种方式结合了前两种的写法,注意它有一个隐藏的坑(见 其他小知识=>1)

4:对象构造

var f = new Function('x', 'y', 'return x+y')

5:=>简写

var f = (x,y) => { }

二、函数的本质

一句话:函数是一个可以执行代码的对象

从内存图角度讲,js函数的本质如下:

d863633fa2372639932fb624415dfa12.png

为更进一步说明函数本质就是一个对象,我们甚至可以自己构造一个“函数”对象,这个对象具有函数功能。

5bfcaf6d6944b2e2dfa5f676c6c1d981.png

三、this和arguments是什么?

前面讲过,函数调用本质上,就是通过函数对象对call方法的调用,该方法参数表如下:

    Function.call(this, arguments[0], arguments[1], ...)

可见,this和arguments,都是Function.call( )的参数

this是call的第一参数;

arguments是call的第二参数起所有参数组成的伪数组,也是函数实际调用时,我们传入的参数表。

事实上,我们每次调用函数

    f(1, 2)

相当于执行方法

    f.call(undefined, 1, 2)

实例:

329f2db236b260b9742ecd45c476e331.png
f(参数表)与f.call(undefined, 参数表)是一样的

b4bf5271ecd560732fc5ae0342b2a53f.png
函数的this,只在f.call()中才能使用
注:arguments是复数形式,不要忘了s
注2:一些Java学习者,看见this难免见名生义,认为它就是“当前对象”;但通过以上分析我们可以看到,JavaScript中this并非对象,它就是一个参数而已。

四、树与作用域

与作用域有关问题容易出错,我们可以画一棵树来描述作用域关系。

1.预备知识a:变量提升

var a = 1在代码中做了两件事:既声明(var a),又赋值(a = 1)。等价于

	var a    //声明
        a = 1    //赋值

变量提升就是将这两件事拆开做:保持a = 1位置不变,将var a提升到所属作用域的最上方。

2.预备知识b:一个函数就是一块作用域,变量的访问遵循就近原则

11607ff81090a425641644d9ebab736d.png
如图

3.用树分析作用域逻辑

在全局范围下,先做一次变量提升,然后把所有声明变量与函数名维护为一个变量数组,这个数组就是一个根节点,里面的变量都是全局变量。

然后从根节点的所有函数出发,每个函数里继续做变量提升,维护变量数组 .... 递归地执行类似操作,就构成了一棵作用域"树"

78926921754e64e1f6a347cb8cbf61d6.png
如图

作用域“树”的用法:

每当我们访问一个变量时,先看所在作用域是否有该变量,有→直接访问,没有→从父亲结点的作用域访问,依此类推。

q:如果顺着父亲结点一直没有找到访问变量,该怎么办呢?

a:这种情况,它会声明全局变量并赋值

007d4c7912111141e31a099d0792ed28.png
可见A的范围是全局的

4. 4个作用域问题

Q1:

fa9b1b340f6cd4e2c8d085e94cd105bf.png

a1:

64f5f71f37b44758b9dc53f24dbfe2c3.png

Q2:

1d723c2b4f87827e8eb551579572c1d8.png

a2:

da4dfbaacad06521a0e59a0f1c96b4cb.png

Q3:

039e11376d6c14d6ddaaf1078cb5633b.png

a3:

10d102aa128f4879445c9a0b1bfbfcfb.png

Q4:

442c9831d8e6f6bda47851d6a9380f65.png

a4:

96d3b8cd82410d619591cadd44929754.png

五、其他小知识

1.函数相关的一个坑

下图中,我们能访问y,不能访问y2

6e2d1f8e5ef4e3b561fa67b7451124dc.png

2.控制台按住"shift + 回车"可以不执行结果换行,继续写代码。

3.什么叫做“stack overflow”?

就是栈上溢,指压栈次数超过最大限制。

0104ae53948becc8148524adb625ca54.png
比如:递归引发栈上溢

4.什么是闭包?

如果一个函数,使用了它范围外的变量,那么(这个函数 + 这个变量)就是闭包。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值