JavaScript作用域原理(一)——作用域链

简介:

一、作用域的描述

JavaScript权威指南中对作用域有一句很精辟的描述:“JavaScript中的函数运行在它们被定义的作用域里,而不是它们被执行的作用域里。”

在JavaScript中,作用域的概念和其他语言差不多,在每次调用一个函数的时候,就会进入一个函数内的作用域,当从函数返回以后,就返回调用前的作用域。

 

验证下刚那句权威指南中的话:

<p id="scope1" style="color:red"></p>
     function echo(p, html) {
            p.innerHTML += html + '<br/>';
        }
        //1、
        var position = 'out';
        var pscope1 = document.getElementById('scope1');
        function scope1() {
            echo(pscope1, position);
        }
        function set1() {
            var position = 'in';
            scope1();
        }
        set1();

1、变量scope1定位到一个p标签,用于打印信息的显示

2、echo是一个自定义的函数,用于打印信息,形参一个是p标签,一个是需要打印的信息内容

3、最后打印出的是“out”,由于打印操作在scope1函数中,scope1中没有变量position,只能往外一层的作用域中查找,作用域关系如下图所示:

4、调用set1的作用域链大致样子如下:

 

二、作用域的实现

作用域的实现,并非用“堆栈”方式,而是使用列表,ECMA262中所述如下:

  1. 任何执行上下文时刻的作用域, 都是由作用域链(scope chain)来实现

  2. 在一个函数被定义的时候, 会将它定义时刻的scope chain链接到这个函数对象的[[scope]]属性

  3. 在一个函数对象被调用的时候,会创建一个活动对象(也就是一个对象), 然后对于每一个函数的形参,都命名为该活动对象的命名属性, 然后将这个活动对象做为此时的作用域链(scope chain)最前端, 并将这个函数对象的[[scope]]加入到scope chain中

 

再来看下两个实例,练练手:

     function function1() {
            var x = 'in function1';
            function inner1() {
                x = 'in inner1'; //没有加var,等同于在外面这个函数中做声明
            }
            inner1();
            echo(pscope1, x);
        }
        function1();

最终打印出来的结果是“in inner1”

 

     function function2() {
            var x = 'in function2';
            function inner2() {
                echo(pscope1, x); 
                var x = 'in inner2'; //加var
                echo(pscope1, x); 
            }
            inner2();
        echo(pscope1, x);
        }
        function2();

第一个echo将打印出“undefined”,第二个echo打印出“in inner2”,第三个echo打印出“in function2”。

上面的inner2等同于下面的代码:

        function inner2() {
                var x
                echo(pscope1, x); //这个时候x还未定义
                x = 'in inner2'; 
                echo(pscope1, x); 
            }

 

 

对作用域链的理解上可能还有些问题,欢迎大家来指正。

 

demo下载:

http://download.csdn.net/detail/loneleaf1/7983577

 

参考资料:

http://www.laruence.com/2009/05/28/863.html Javascript作用域原理

http://www.cnblogs.com/lhb25/archive/2011/09/06/javascript-scope-chain.html JavaScript 开发进阶:理解 JavaScript 作用域和作用域链

http://www.cnblogs.com/zxj159/archive/2013/05/30/3107923.html Javascript之匿名函数(模仿块级作用域)

http://www.web-tinker.com/article/20331.html try-catch语句的“伪块作用域”

http://msdn.microsoft.com/zh-cn/library/bzt2dkta%28v=vs.94%29.aspx 变量作用域 (JavaScript)

http://www.cnblogs.com/rubylouvre/archive/2009/08/21/1551270.html javascript变量的作用域

http://www.nowamagic.net/librarys/veda/detail/896 深入浅出JavaScript变量作用域





    本文转自 咖啡机(K.F.J)   博客园博客,原文链接:http://www.cnblogs.com/strick/p/3992745.html,如需转载请自行联系原作者


相关文章
|
15天前
|
存储 JavaScript 前端开发
解释 JavaScript 中的作用域和作用域链的概念。
【4月更文挑战第4天】JavaScript作用域定义了变量和函数的可见范围,静态决定于编码时。每个函数作为对象拥有`scope`属性,关联运行期上下文集合。执行上下文在函数执行时创建,定义执行环境,每次调用函数都会生成独特上下文。作用域链是按层级组织的作用域集合,自内向外查找变量。变量查找遵循从当前执行上下文到全局上下文的顺序,若找不到则抛出异常。
20 6
|
1月前
|
自然语言处理 JavaScript 前端开发
探索JavaScript中的闭包:理解其原理与实际应用
探索JavaScript中的闭包:理解其原理与实际应用
19 0
|
1月前
|
JavaScript
JS数组增删方法的原理,使用原型定义
JS数组增删方法的原理,使用原型定义
|
26天前
|
JavaScript 前端开发
js开发:请解释什么是作用域(scope),并说明全局作用域、局部作用域和块级作用域的区别。
JavaScript中的作用域规定了变量和函数的可见性与生命周期。全局作用域适用于整个脚本,变量可通过全局对象访问,可能导致命名冲突和内存占用。局部作用域限于函数内部,每次调用创建新作用域,执行完毕后销毁。ES6引入的块级作用域通过`let`和`const`实现,变量仅在其代码块内有效,并有暂时性死区。作用域机制有助于代码组织和变量管理。
23 1
|
1月前
|
自然语言处理 前端开发 JavaScript
深入理解JavaScript中的闭包与作用域链
在JavaScript编程中,闭包和作用域链是两个非常重要的概念,它们对于理解代码的执行过程和解决一些特定问题至关重要。本文将深入探讨JavaScript中闭包和作用域链的原理和应用,帮助读者更好地理解这些概念并能够在实际项目中灵活运用。
|
1月前
|
JavaScript
JS中call()、apply()、bind()改变this指向的原理
JS中call()、apply()、bind()改变this指向的原理
|
1月前
|
JavaScript 前端开发
JS作用域与作用域链
JS作用域与作用域链
|
1月前
|
JavaScript 前端开发 API
Vue.js 深度解析:nextTick 原理与应用
Vue.js 深度解析:nextTick 原理与应用
|
1月前
|
自然语言处理 JavaScript 前端开发
深入探索 JS 的提升机制、函数与块作用域以及函数表达式和声明(下)
深入探索 JS 的提升机制、函数与块作用域以及函数表达式和声明(下)
|
1月前
|
JavaScript 前端开发
深入探索 JS 的提升机制、函数与块作用域以及函数表达式和声明(上)
深入探索 JS 的提升机制、函数与块作用域以及函数表达式和声明(上)