认识javascript范围和作用域链
范围
作用域就是变量和函数的可訪问范围。控制着变量和函数的可见性与生命周期,在JavaScript中变量的作用域有全局作用域和局部作用域。
全局和局部作用域以下用一张图来解释:
单纯的JavaScript作用域还是非常好理解的。
作用域链
全局运行环境是最外层的一个运行环境,在web浏览器中全局运行环境是window对象,因此全部全局变量和函数都是作为window对象的属性和放大创建的。每一个函数都有自己的运行环境,当运行流进入一个函数的时候。函数的环境会被推入一个函数栈中。而在函数运行完成后运行环境出栈并被销毁,保存在当中的全部变量和函数定义随之销毁,控制权返回到之前的运行环境中,全局的运行环境在应用程序退出(浏览器关闭)才会被销毁。
当代码在一个环境中运行时。会创建变量对象的一个作用域链(scope chain)来保证对运行环境有权訪问的变量和函数的有序訪问。
用一张图来解释作用域链的执行:由里向外执行。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemx0czAwMA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
当一个函数创建后。它的作用域链会被创建此函数的作用域中可訪问的数据对象填充,比如定义以下这样一个函数:
- function add(num1,num2) {
- var sum = num1 + num2;
- return sum;
- }
在函数add创建时,它的作用域链中会填入一个全局对象,该对象包括了全部全局变量。例如以下图所看到的:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemx0czAwMA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
函数add的作用域将会在运行时候用到。比如运行例如以下代码:
- function a(sum1,sum2){
- var sum=num1+num2;
- return sum;
- }
- var tatal=a(5,10);
执行此函数时会创建一个称为“执行期上下文(execution context)”的内部对象,执行期上下文定义了函数执行时的环境。每一个执行期上下文都有自己的作用域链,用于标识符解析,当执行期上下文被创建时。而它的作用域链初始化为当前执行函数的[[Scope]]所包括的对象。
这些值依照它们出如今函数中的顺序被拷贝到执行期上下文的作用域链中。它们共同组成了一个新的对象,叫“活动对象(activation object)”,该对象包括了函数的全部局部变量、命名參数、參数集合以及this,然后此对象会被推入作用域链的前端。当执行期上下文被销毁,活动对象也随之销毁。新的作用域链例如以下图所看到的:
在函数运行过程中,没遇到一个变量,都会经历一次标识符解析过程以决定从哪里获取和存储数据。该过程从作用域链头部。也就是从活动对象開始搜索,查找同名的标识符。假设找到了就使用这个标识符相应的变量,假设没找到继续搜索作用域链中的下一个对象,假设搜索全然部对象都未找到。则觉得该标识符没有定义。
总结
依据上述讲的作用域链的结构能够看出,定义的标识符的越深。那么读写的速度也就越慢。而全局变量总是处于作用域链的最末端。所以当变量解析的时候,查找全局变量是最慢的,所以在编写代码的时候要尽可使用全局变量的可以少。使用局部变量越好。
版权声明:本文博客原创文章,博客,未经同意,不得转载。
认识javascript范围和作用域链的更多相关文章
- javascript的关键所在---作用域链
javascript的关键所在---作用域链 javascript里的作用域是理解javascript语言的关键所在,正确使用作用域原理才能写出高效的javascript代码,很多javascript ...
- javascript闭包和作用域链
最近在学习前端知识,看到javascript闭包这里总是云里雾里.于是翻阅了好多资料记录下来本人对闭包的理解. 首先,什么是闭包?看了各位大牛的定义和描述各式各样,我个人认为最容易一种说法: 外部函数 ...
- javascript笔记:javascript的关键所在---作用域链
javascript里的作用域是理解javascript语言的关键所在,正确使用作用域原理才能写出高效的javascript代码,很多javascript技巧也是围绕作用域进行的,今天我要总结一下关于 ...
- Javascript——闭包、作用域链
1.闭包:是指有权访问另一个函数作用域中的变量的函数.创建闭包的常见方式:在一个函数内部创建另一个函数. function f(name){ return function(object){ var ...
- [译]JavaScript:函数的作用域链
原文:http://blogs.msdn.com/b/jscript/archive/2007/07/26/scope-chain-of-jscript-functions.aspx 在JavaScr ...
- JavaScript中的作用域链原理
执行环境 作用域链的形成与执行环境(Execution Environment)相关,在JavaScript当中,产生执行环境有如下3中情形: 1 进入全局环境 2 调用eval函数 3 调用func ...
- javascript 关于 this 作用域链
使用 function f() {} 或者 var f = function() {} 来定义的函数,this 是指向 全局对象 var a = { b: 1, c: funct ...
- javascript深入浅出图解作用域链和闭包
一.概要 对于闭包的定义(红宝书P178):闭包就是指有权访问另外一个函数的作用域中的变量的函数. 关键点: 1.闭包是一个函数 2.能够访问另外一个函数作用域中的变量 文章首发地址于sau交流学习社 ...
- JavaScript深入之作用域链
前言 在 <javascript深入之执行上下文栈> 中讲到,当javascript代码执行一段可执行代码(executable code)时,会创建对应的执行上下文(execution ...
随机推荐
- HDU 4454 - Stealing a Cake(三分)
我比较快速的想到了三分,但是我是从0到2*pi区间进行三分,并且漏了一种点到边距离的情况,一直WA了好几次 后来画了下图才发现,0到2*pi区间内是有两个极值的,每个半圆存在一个极值 以下是代码 #i ...
- Netbeans源代码编辑技巧——使用代码补全和代码生成
原文 Netbeans源代码编辑技巧——使用代码补全和代码生成 使用代码补全生成代码 一般来说,代码补全对于自动填充缺失的代码是有帮助的,例如标识符和关键字.截至 NetBeans IDE 6.0,您 ...
- Audio Offload
Audio Offload 音频分载,是系统将音频分载到声卡硬件进行分载处理的功能.从Windows 8开始,音频的硬件加速和分载处理又回来了.为什么说又回来了呢? 因为声卡自创通公司发明开始,相当长 ...
- LeetCode——Container With Most Water
Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). ...
- 深入理解Oracle RAC 12c 笔记
深入理解Oracle RAC 12c 跳转至: 导航. 搜索 文件夹 1 概述 2 集群件管理和故障诊断 3 执行实践 4 新特性 5 存储和ASM 6 应用设计上的问题 7 管理和调优一个复杂的RA ...
- Ubuntu12.10 下搭建基于KVM-QEMU的虚拟机环境(十三)
今天我们实验libvirt提供的快照功能,快照可以用于系统恢复,防止安装了某些软件或中病毒等情况导致系统损毁的情况. 一.快照类型 1) 磁盘快照 内部的:快照驻留在原来的镜像文件内部 ...
- Oracle练习
--声明一个变量,并给它赋值 declare v_bonus number(8); begin select id*6 into v_bonus from A where Id=5; DBMS_OU ...
- LeetCode——Valid Sudoku
Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could be ...
- Django中的一些同步Model和数据库的命令
1 最简单而又令人兴奋的命令: manage.py syncdb 创建了指定app中的model相应的数据库表,假设是第一次使用此命令,会提示是否创建超级用户,输入username,Email和pas ...
- 【PhotoShop】采用PS让美丽的咖啡泡沫
稀土一杯咖啡,如何你不能击败张(常苦黑咖啡饮料实在受不了! ) 得到例如以下图 看着还不错,但是总感觉空空荡荡的,所以就拿来PS练手了.终于效果图例如以下: 以下讲下制作过程: 首先是给照片加下咖啡泡 ...