发表于: 2019-03-08 22:46:32

1 531


今天完成的事:

复习

明天计划的事:

复盘  复习

遇到的问题:

解决方案:

JS 执行环境作用域“链”

 执行环境 定义了变量和函数有权限访问其它数据,决定了它们的各自行为。每个执行环境都有一个与之关联的变量对象,环境中定义的变量和函数都被保存在这个变量对象中

 “我们编写的代码无法访问这个对象,但解析器在处理数据时会在后台使用它”。当代码在一个执行环境中执行时,会创建变量对象的一个作用域链,作用域链的作用是保证执行环境有权访问所有变量和函数的有序访问。也可以把作用域链看做是一个集合,最前端的是当前的执行环境的对象,最后面的是全局执行环境的对象。如果环境是韩式,则将其活动对象作为变量对象,活动对象最开始只包含一个变量就是“arguments”对象(这个对象在全局环境中是不存在的)。

程序执行时,环境栈与执行环境的关系

   当执行流进入一个函数时,即该函数正在执行,函数的执行环境就会被推入一个环境栈中,所有处在执行流的执行环境将有次序地保存在环境栈中,在函数执行之后,栈将其执行环境弹出,把控制权交给原来的执行环境。所以在程序执行中,环境栈是不断变化的,伴随着执行环境的出入,如下所示:



JavaScript中每个函数都会有一个Arguments对象的实例arguments,它引用着函数的实参,而且可以用数组下标的方式来引用arguments的元素。 arguments.length为函数实参的个数,要注意的是,arguments对象并不是一数组,它也不具有数组的所有方法,但是访问单个参数的方式与访问数组元素的方式相同


arguments 三个用处

一、实现重载
我们都知道,在JavaScript中并没有函数重载的功能,但是Arguments对象能够模拟重载,比如,最简单的一种方式,根据参数的个数进行重载。如下图


利用Arguments对象实现函数重载的方式可以有几种,除了根据参数的个数,还可以根据传入参数的类型来执行不同的操作,也可以利用参数中特殊的参数值来进行不同的操作。
二、同数组下标访问实参
JavaScript中每个函数都会有一个Arguments对象的实例arguments,它引用着函数的实参,而且可以用数组下标的方式来引用arguments的元素。如下图

如上图代码所示,arguments.length为函数实参的个数,要注意的是,arguments对象并不是一数组,它也不具有数据的所有方法,但是访问单个参数的方式与访问数组元素的方式相同,如上图代码中argument[0]...。
三、属性callee指向自己
对象都是有自己的属性和方法的,Arguments对象也是一样,callee就是它的方法,这个方法用的不多,很容易被我们忽略,它指向的是正在被执行的Function对象,最常用的例子就是用来做递归了。如下图

如上图代码所示,实现了6+5+4+3+2+1的操作。
最后总结:
在平时的封装和使用JS过程中,callee方法用的比较少,其它一般都会用到,现在,我在用几句话在来总结一下对arguments的理解:
1、arguments像数组,是一个Arguments对象实例。
2、arguments有length属性,代表传给函数的参数个数。
3、可以数组下标访问参数,如arguments[0],无数组其它方法。
4、存储的是实参不是行参。

5、可以使用callee属性调用自身。


延长作用域链
with会将指定的对象添加到作用域链的前端(添加一个变量对象)

会先在  with新添加的这个对象 b的执行环境中寻找a“678”,当找到了就不会再用函数li()执行环境中的a“th”

                                                                         
全局执行环境是最外围的一个执行环境,全局执行环境被认为是window对象,因此所有的全局变量和函数都是作为window对象的属性和方法创建的。当某个执行环境(局部执行环境)所有代码执行完毕后,该环境会自动销毁,保存在其中的变量和函数定义也随之销毁,全局执行环境直到关闭程序,比如关闭网页和浏览器时才会销毁。

每个函数都有自己的执行环境,也就是局部执行环境,当执行流进入一个函数体时,函数的环境会被推入一个环境栈中,当函数执行之后,环境栈将其弹出。


作用域: 变量或方法有访问权限的代码空间,即变量或函数起作用的区域。(作用域包括全局作用域与函数作用域,没有块级块作用域,即一个变量的作用域不可能是一个块级域,至少包括最临近的整个函数空间。


作用域与变量对象,执行环境的关系

  由定义可知,作用域即函数或变量的作用区域。

  变量或函数具有作用域的原因,就是在环境中定义的变量仅保存在了该执行环境对应的对象变量中,执行环境在环境栈中弹出之后,作用域链中找不到该对变量对象,以下面为例


 为什么在全局环境下showColor()内定义的变量不可访问呢,这是因为当函数执行到该语句时,color变量保存在了showColor()环境对应的变量对象中,现在showColor()已经执行完毕,该执行环境也从环境栈中弹出并销毁,所以此时的作用域链也不包括showColor()的执行环境对应的变量对象了,因为标识符解析是顺着作用域链查找变量的,所以这个过程不再能搜索到color变量,所以color变得只有定义该变量的函数中才能访问,具有一定范围的作用域。









返回列表 返回列表
评论

    分享到