您的位置:首页 > Web前端 > JavaScript

Js作用域之词法作用域和动态作用域

2017-10-11 11:18 155 查看
作者在学习的过程中偶然看见了词法作用域一词,于是对其进行了进一步的学习,下面分享一篇我看到的比较好的文章(本文有少许改动)。

作用域分为词法作用域和动态作用域,词法作用域也称静态作用域。词法作用域是在程序源代码书写时就确定的,而动态作用域则是在运行时确定的。目前大部分语言使用的都是词法作用域,JavaScript也是。

一、词法作用域

词法作用域是由编写代码时将变量和作用域写在哪里来决定的,即词法作用域的定义过程发生在代码的书写阶段,因而词法分析器处理代码时会保持作用域不变。无论函数在哪里被调用,也无论它如何被调用,他的词法作用域都只由函数声明时所处位置决定。举个例子。

function a(){
var a;
function b(){
var b;
}
}


在全局作用域中,有一个函数a;在函数a的局部作用域中,有一个变量a和函数b;在函数b的局部作用域中,有一个变量b;

当我们查找变量a时,它首先从最内部的作用域也就是函数b的作用域开始查找。当引擎无法在这里找到时,它将会到其包含作用域(父作用域)继续查找,在这里找到了a,引擎就使用了这个引用。变量b同理,引擎直接在最内层函数b的作用域中找到了它。

注意:作用域查找是从内部逐层向外查找的,直至遇见第一个匹配的标识符位置。故而如果此时更外层还有同名的标识符,内层的同名标识符会屏蔽它。

二、动态作用域

动态作用域不关心函数和作用域是任何声明以及在何处声明的,只关心他们在何处调用。换句话说,作用域链是基于调用栈的,而不是代码中的作用域嵌套。

var a = 2;
function foo() {
console.log( a );
}
function bar() {
var a = 3;
foo();
}
bar();


【1】如果处于词法作用域,也就是现在的javascript环境。变量a首先在foo()函数中查找,没有找到。于是顺着作用域链到全局作用域中查找,找到并赋值为2。所以控制台输出2

【2】如果处于动态作用域,同样地,变量a首先在foo()中查找,没有找到。这里会顺着调用栈在调用foo()函数的地方,也就是bar()函数中查找,找到并赋值为3。所以控制台输出3

所以说你该知道了吧!两种作用域的区别,简而言之,词法作用域是在定义时确定的,静态作用域规则查找一个变量声明时依赖的是源程序中块之间的静态关系;而动态作用域是在运行时确定的,动态作用域规则依赖的是程序执行时的函数调用顺序。

原文链接:(本文有少许改动)http://www.cnblogs.com/xiaohuochai/archive/2016/07/24/5700095.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息