浅谈javascript中执行环境(作用域)与作用域链

相信很多初学者对与javascript中的执行环境与作用域链不能很好的理解,这里,我会按照自己的理解同大家一起分享。

一般情况下,我们把执行环境分为全局执行环境和局部执行环境,其中局部执行环境我们又可以称之为函数执行环境。那么究竟什么使执行环境呢?通俗的说,执行环境即为代码执行时所处的环境。我们下来看一看如下代码,再进一步分析之。

<script><br>var name="zhuzhenwei";
function changeName(){
    if (name=="zhuzhenwei"){
          name="heting";
    }else{
          name="zhuzhenwei";
    }
}
changeName();
console.log(name); //heting<br></script>

如上述代码,当执行第一个语句时,该语句所在的环境为全局执行环境,应当注意的是:每个执行环境都有一个与之相关联的变量对象,对于全局执行环境,与它向关联的对象为window对象。紧接着,下面这条语句声明了一个函数(注意:这里仅仅是声明了函数,没有被调用之前是不会执行内部代码的)。  同样这个函数也是处于全局执行环境的。最后,我们调用了changeName()函数,一旦调用了该函数,那么立即跳转到了changeName()函数的执行环境(即函数执行环境),一旦进入执行环境,便开始创建函数内部相应的变量(如函数中假设出现var a=12;这样的代码),不调用函数是不会创建的,且与之相关的变量对象我们认为是活动对象(活动对象开始只包含一个变量,即arguments对象),自此开始从上到下执行语句。与此同时,代码在函数环境中执行时,就会创建变量对象的一个作用域链,这个作用域链包含changeName()的变量对象和全局变量对象。

作用域链实际上就是我们可以通过它从前端到末端可以访问的范围,即保证对执行环境有权访问的所有变量和函数的有序访问,其中前端是指当前执行代码所在的变量对象,这里现在就是changeName()函数的变量对象,末端是全局变量对象,比如说:我们在执行函数时,需要寻找一个标识符,这是就是通过作用域链的末端进行寻找,若作用域链的末端找不到,就一直向上寻找,直到window对象。虽然在全局环境中我没有提到作用域链,但实际上全局环境中作用域链也是存在的,只是只有一个全局变量对象。 很明显:访问局部变量比访问全局变量更快,因为不用向上搜索作用域链。显然,作用域链是随着代码所处的执行环境的不同而动态变化的。

当执行完changeName()函数之后,即函数执行环境中的代码执行完成之后,该环境中的局部变量和局部对象会被立即销毁(如果变量没有用var声明,表明是全局变量不会在局部环境的代码执行之后销毁),随即执行环境由函数执行环境转向全局执行环境,继续执行console.log(name);语句。只是,如果我们关闭网页或浏览器,全局环境也将被销毁。

总结如下:

  • 执行环境也成为作用域,执行环境决定了变量的生命周期。
  • 执行环境有全局执行环境和局部执行环境之分,每进入一个执行环境就会创建一个用于搜索变量和函数的作用域链,于是我们认为这个作用域链是动态变化的。
  • 函数的局部环境不仅有权访问函数作用域中的变量,而且有权访问其包含环境(父环境),乃至全局环境;而全局环境只能访问在全局环境中定义的变量和函数(局部环境中未使用var声明的变量也属于全局变量),不能访问局部环境中的数据(没有说所有数据,正是因为全局变量可以访问)。注意:函数中的参数时函数的局部变量。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,同时也希望多多支持我们!

(0)

相关推荐

  • javascript基础进阶_深入剖析执行环境及作用域链

    执行环境 执行环境定义了变量或函数有权访问的其他函数,决定了他们各自的行为.每个执行环境都有一个与之关联的变量对象. 变量对象 环境中定义的所有变量和函数都保存在这个对象中. 全局执行环境 全局执行环境是最外围的一个执行环境.在web浏览器中,全局执行环境被认为是Window对象,因此所有全局变量和函数都是作为window对象的属性和方法创建的. 每个函数都有自己的执行环境. 作用域链 当代码在一个环境中执行,会创建变量对象的一个作用域链. 用途:保证对执行环境有权访问的所有变量和函数有序访问.

  • js 函数的执行环境和作用域链的深入解析

    第一步. 定义后:每个已定义函数,都有一个内在属性[scope],其对应一个对象的列表,列表中的对象仅能内部访问. 例如:建立一个全局函数A,那么A的[Scope]内部属性中只包含一个全局对象(Global Object),而如果我们在A中创建一个新的函数B,那么B的[Scope]属性中就包含两个对象,函数A的Activation Object对象在前面,全局对象(Global Object)排在后面. 简而言之,一个函数的[Scope]属性中对象列表的顺序是上一层函数的Activation O

  • javascript作用域链与执行环境详解

    前言:这是笔者学习之后自己的理解与整理.如果有错误或者疑问的地方,请大家指正,我会持续更新! 作用域.作用域链.执行环境.执行环境栈以及this的概念在javascript中非常重要,本人经常弄混淆,这里梳理一下: 局部作用域函数内部的区域,全局作用域就是window: 作用域链取决于函数被声明时的位置,解析标识符的时候就先找当前作用域,再向外查找,直到全局,这样一个顺序:和函数在哪里调用无关: 执行环境就是函数可访问的数据和变量的集合,也就是函数的作用域链上的所有数据和变量: 执行环境栈就是根

  • javascript执行环境及作用域详解

    最近在重读<javascript高级程序设计3>,觉得应该写一些博客记录一下学习的一些知识,不然都忘光啦.今天要总结的是js执行环境和作用域. 首先来说一下执行环境 一.执行环境         书上概念,执行环境定义了变量或者函数有权访问的其他数据,决定了他们各自的行为.每个执行环境都有一个与之关联的变量对象.环境中定义的所有变量和函数都保存在这个对象中.虽然我们在编写代码的时候无法访问这个对象,但解析器在处理数据时会在后台用到它. 执行环境是一个概念,一种机制,它定义了变量或函数是否有权访

  • 老生常谈原生JS执行环境与作用域

    首先,我们要知道执行环境和作用域是两个完全不同的概念. 函数的每次调用都有与之紧密相关的作用域和执行环境.从根本上来说,作用域是基于函数的,而执行环境是基于对象的(例如:全局执行环境即window对象). 换句话说,作用域涉及到所被调用函数中的变量访问,并且不同的调用场景是不一样的.执行环境始终是this关键字的值,它是拥有当前所执行代码的对象的引用.每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中.虽然我们编写的代码无法访问这个对象,但解析器在处理数据时会在

  • 浅谈javascript中执行环境(作用域)与作用域链

    相信很多初学者对与javascript中的执行环境与作用域链不能很好的理解,这里,我会按照自己的理解同大家一起分享. 一般情况下,我们把执行环境分为全局执行环境和局部执行环境,其中局部执行环境我们又可以称之为函数执行环境.那么究竟什么使执行环境呢?通俗的说,执行环境即为代码执行时所处的环境.我们下来看一看如下代码,再进一步分析之. <script><br>var name="zhuzhenwei"; function changeName(){ if (name

  • 浅谈Javascript中的函数、this以及原型

    关于函数 在Javascript中函数实际上就是一个对象,具有引用类型的特征,所以你可以将函数直接传递给变量,这个变量将表示指向函数"对象"的指针,例如: function test(message){ alert(message); } var f = test; f('hello world'); 你也可以直接将函数申明赋值给变量: var f = function(message){ alert(message); }; f('hello world'); 在这种情况下,函数申明

  • 浅谈JavaScript中this的指向问题

    JavaScript中this指向问题 记得初学 JavaScript 时,其中 this 的指向问题曾让我头疼不已,我还曾私自将其与闭包.原型(原型链)并称 JS 武林中的三大魔头.如果你要想在 JS 武林中称霸一方,必须将这三大魔头击倒.个人认为在这三大魔头中,this 指向问题的武功最菜(难度最低).俗话说柿子捡软的捏,那我们就先从 this 指向问题下手. 先记住攻克 this 指向问题的口诀(前辈们的总结):哪个对象调用函数,函数里的 this 就默认指向哪个对象(注意 this 只能

  • 浅谈JavaScript中this的指向更改

    JS中this指向的更改 JavaScript 中 this 的指向问题前面已经总结过,但在实际开中, 很多场景都需要改变 this 的指向. 现在我们讨论更改 this 指向的问题. call更改this指向 call 的使用语法:func.call(thisArg, arg1, arg2, ...) call 方法需要一个指定的 this 值( this要指向的对象 )和一个或者多个参数.提供的 this 值会更改调用函数内部的 this 指向. // 使用 call 方法改变调用函数执行上

  • 浅谈javascript中的Function和Arguments

    javascript的Function 属性: 1.Arguments对象 2.caller 对调用单前函数的Function的引用,如果是顶层代码调用,  则返回null(firefox返回undefined).  注:只有在代码执行时才有意义 3.length 声明函数是指定的命名参数的个数(函数定义是,定义参数的个数) 4.prototype 一个对象,用于构造函数,这个对象定义的属性和方法  由构造函数创建的所有对象共享. 方法: applay() --> applay(this,[])

  • 浅谈JavaScript中变量和函数声明的提升

    现象: 1. 在JavaScript中变量和函数的声明会提升到最顶部执行. 2. 函数的提升高于变量的提升. 3. 函数内部如果用var声明了相同名称的外部变量,函数将不再向上寻找. 4. 匿名函数不会提升. 5. 不同<script>块中的函数互不影响. 例子: 函数声明提升高于变量声明 //同时声明变量a和函数a var a; function a() {} alert(typeof a); //显示的是"function",初步证明function的优先级高于var.

  • 浅谈JavaScript中数组的增删改查

    数组的增加 •ary.push()   向数组末尾添加元素,返回的是添加后新数组的长度,原有数组改变 •ary.unshift()  向数组开头添加元素,返回的是添加后新数组的长度,原有数组改变 • var ary=[1,2,3,4];   var res=ary.unshift(6);   console.log(res); ---->5 返回的是新数组的长度•ary.splice(n,m,x)从索引n开始删除m个元素,把新增的元素X放在索引n的前面,把删除的元素当成一个新数组返回,原有数组改

  • 浅谈JavaScript中的分支结构

    说到JavaScript中的分支结构,我们就不得不提到流程控制这个词,我们所有的程序都是由数据和算法组成的. 程序=数据+算法 通常我们所说的算法都可以通过"顺序","分支","循环"三种结构来组合完成. 在ECMA中规定了一些语句(也称为流程控制语句,分支结构语句),从本质上来说,这些语句定义了ECMAScript中的主要语法,语句通常使用一个或者多个关键字来完成给定任务. 1.1 if 语句 if 语句 - 只有当指定条件为 true 时,使

  • 浅谈JavaScript中的属性:如何遍历属性

    在JavaScript中,遍历一个对象的属性往往没有在其他语言中遍历一个哈希(有些语言称为字典)的键那么简单.这主要有两个方面的原因:一个是,JavaScript中的对象通常都处在某个原型链中,它会从一个或多个的上层原型上继承一些属性.第二个原因是,JavaScript中的属性不光有值,它还有一些除了值以外的其他特性,其中一个影响属性遍历的特性就是[[Enumerable]],如果该值为true,则称这个属性是可枚举的,否则反之. 知道了这些,我们就可以把属性的遍历分为四种情况. 注:示例代码中

  • 浅谈JavaScript中的对象及Promise对象的实现

    JavaScript 中的所有事物都是对象:字符串.数值.数组.函数.下面小编给大家收集整理些javascript中的对象及promise对象的实现.具体内容如下: 到处都是对象 window对象 常用的属性和方法介绍 location 包含页面的URL,如果改变这个属性,浏览器会访问新的URL status 包含将在浏览器状态去显示的一个串.一般在浏览器左下角 onload: 包含了需要在页面完全加载后调用的函数 document: 包含DOM alert方法: 显示一个提醒 prompt方法

随机推荐