javascript作用域链理解

执行上下文(Execution context,简称EC)

概念

每当控制器到达ECMAScript可执行代码的时候,就进入了一个执行上下文。

javascript中,EC分为三种:

全局级别的代码(全局执行上下文)

函数级别的代码(函数执行性上下文)

Eval的代码(eval执行上下文)

执行上下文对象包括三个关键属性,可能有其他自定义属性。

VO(Variable object), 变量对象 或者 AO(activation object),活动对象,是个字典,包括函数arguments对象,形参,内部变量,函数声明

Scope chain,作用域链对象,包括当前作用域的vo和所有父级作用域的vo。

this对象,Context object,上下文对象。

作用域链的链式结构

作用域链的链式结构,是AO有个父级变量对象的引用,用

__parent__内部属性指代。则通过对父级的应用形成一种

链式结构,如下图

作用域链结构图片

执行上下文的执行过程

EC的建立分为两个阶段:进入执行上下文阶段和代码执行阶段

1.进入上下文阶段

发生在函数调用时,在执行具体代码之前。做如下三件事:

创建作用域链(Scope Chain)

创建变量对象

设置this对象的值,this对象的值取决于对象的调用者,caller和调用方式决定了this的值。

变量对象中的变量值如下:

根据函数参数创建并初始化arguments对象

函数声明创建属性,关联具体函数

变量初始化为undefined(所谓变量提升)

同名覆盖原则

函数声明与参数同名 函数声明覆盖参数

变量与函数声明或参数同名,变量赋值前其有效

2.代码执行阶段

变量赋值

解释执行其他代码

执行上下文的创建会形成一个栈,新创建的执行上下文入栈,执行完毕则出栈。

程序执行时,首先进入全局执行上下文,Global Context入栈,

在全局中有函数调用,则会进入函数执行上下文,函数执行上下文入栈

执行上下文栈 图片

闭包

定义

包含自由变量的函数就是闭包(自由变量指不是函数参数,也不是函数内部变量的变量,即外部变量)
该函数通常为内部函数,被返回,外部可以引用该函数,通过其访问自由变量。

闭包的用途

1. 读取函数内部的变量
2. 让变量的值始终保持在内存中,比如循环注册事件,在事件中访问循环变量,需要用闭包来保持循环变量
3. IIFE(立即调用的函数表达式),在引用了外部变量的时候,也会形成闭包,形成一个独立的作用域,防止变量污染

闭包注意点

1. 闭包会使得父级作用域的变量都被保存在内存中,内存消耗大,在IE中可能会导致内存泄漏。少用闭包,或者将不使用的局部变量全部删除
2. 父级作用域的变量是共享,一个闭包修改了变量的值,其他闭包的值获取的值也会发生变化,容易产生错误

时间: 2024-10-19 13:23:20

javascript作用域链理解的相关文章

JavaScript作用域链

JavaScript作用域链 之前写过一篇JavaScript 闭包究竟是什么的文章理解闭包,觉得写得很清晰,可以简单理解闭包产生原因,但看评论都在说了解了作用域链和活动对象才能真正理解闭包,起初不以为然,后来在跟公司同事交流的时候发现作用域和执行环境确实很重要,又很基础,对理解JavaScript闭包很有帮助,所以在写一篇对作用域和执行环境的理解. 作用域 作用域就是变量和函数的可访问范围,控制着变量和函数的可见性与生命周期,在JavaScript中变量的作用域有全局作用域和局部作用域. 单纯

(好文推荐)一篇文章看懂JavaScript作用域链

闭包和作用域链是JavaScript中比较重要的概念,首先,看看几段简单的代码. 代码1: 1 var name = "stephenchan"; 2 var age = 23; 3 function myFunc() { 4 alert(name); 5 var name = "endlesscode"; 6 alert(name); 7 alert(age); 8 alert(weight); 9 } 10 myFunc(); 11 myFunc(); 上述代码

【转】javascript 作用域链

JavaScript函数的作用域链分为定义时作用域链和运行时作用域链: 函数被定义的时候,它有一个属性[[scope]]标明它的定义作用域链,定义时作用域链[[scope]]遵守这样的规则:一个函数的定义时作用域链[[scope]]总是它所在的外部函数的执行时作用域链: 全局函数的定义作用域链只包含window的属性: 一个函数的执行时作用域链总是在定义时作用域链的头部压入当前活动对象(它包含this,arguments,参数,局部变量): 函数执行时,变量寻址总是从作用域链的顶端朝下寻找:所以

JavaScript 作用域链图详解

<script type="text/javascript"> /** * 作用域链: */ var a = "a"; function hao947(){ var b = "b"; alert(a);// output a alert(b);// output b // alert(c);// output undefind function hao(){ var c = "c"; alert(a);// out

JavaScript 作用域链图具体解释

<script type="text/javascript"> /** * 作用域链: */ var a = "a"; function hao947(){ var b = "b"; alert(a);// output a alert(b);// output b // alert(c);// output undefind function hao(){ var c = "c"; alert(a);// out

javascript学习中自己对作用域和作用域链理解

在javascript学习中作用域和作用域链还是相对难理解些,下面我关于javascript作用域和作用域链做一下详细介绍,给各位初学者答疑解惑. 首先我们介绍一下什么是作用域?  从字面上理解就是起作用的区域.   作用域主要有两种作用域:      1.块级作用域(js 不支持):主要用于C系列语言中,例如:Java Object-c/Swift(苹果开发语言).C++/C#.在此不做过多说明.      2.词法作用域  一个变量的作用范围,在代码写出来的那一刻就定下来了,不会根据代码的运

个人理解的javascript作用域链与闭包

闭包引入的前提个人理解是为从外部读取局部变量,正常情况下,这是办不到的.简单的闭包举例如下: 1 function f1(){ 2 3 n=100; 4 5 function f2(){ 6 alert(n); 7 } 8 9 return f2; 10 11 } 12 13 var result=f1(); 14 15 result(); // 100 代码中的f2函数,就是闭包. 1 function f1(){ 2 3 var n=100; 4 5 nAdd=function(){n+=1

深入理解javascript作用域链

之前作用域链在我眼里也只是在调用一个对象时一层一层向上找到自己所需的变量或是函数,若没有则返回undefined,其实大致上说却是这样的,但是我需要的是不断的深入. 在深入理解之前先记住两句话 1.js中一切皆对象,函数也是对象 2.函数运行在他们被定义的作用域内,而不是被执行的作用域内. 当定义函数时,会包含[[scope]]属性(因为js中一切皆对象,函数也是对象),此属性是函数内部属性,只允许js引擎访问,[[scope]]指向作用域链(scope lain),而此时仅包含 所有全局变量.

JavaScript 作用域链解析

JavaScript 中有 Scope( 作用域 ) , Scope chain( 作用域链 ) , Execute context( 执行上下文 ) , Active Object ( 活动对象 ),Dynamic Scope( 动态作用域 ) , Closure( 闭包 ) 这些概念,要理解这些概念,我们从静态和动态两个方面去分析一下. 首先我们写一个简单的 function 来做一个例子: function add(num1, num2){ var sum = num1 + num2; r