Javascript:对作用域链的认识

作用域链

作用域:提高了程序逻辑的局部性,增强程序的可靠性,减少名字冲突。
看一个例子:

var s1 = 'sharpxiajun';

function ftn(){
  var s2 = 'xtq';
  
  console.log(this); //window
  console.log('s1:' + this.s1 + ';s2:' + this.s2); // s1:sharpxiajun;s2:undefined
  console.log('s1:'+this.s1+';s2:' + s2); //s1:sharpxiajun;s2:xtq
}
ftn();

在javascript世界里有一个大的作用域环境,这个环境就是window,window环境不需要我们自己使用什么方式构建,页面加载时候页面会自动构造的,上面代码里有一个大括号,这个大括号是对函数的定义,运行时,我们发现函数作用域内部定义的s2变量是不能被window对象访问的,因此s2变量是被{}保护起来了,它的生命周期和这个函数的生命周期有关。

在javascript里作用域有一个专门的定义execution context,叫执行上下文或执行环境,我们来想想javascript里那些情况是执行:
情况一:当页面加载时候在script标签下的javascript代码会按顺序执行,而这些能被执行的代码都是属于window的变量或函数;
情况二:当函数的名字后面加上小括号(),例如ftn(),这也是在执行,不过它执行的是函数。

如此说来,javascript里的执行环境有两类一类是全局执行环境,即window代表的全局环境,一类是函数代表的函数执行环境,这也就是我们常说的局部作用域。

执行环境在javascript语言里并非是一个抽象的概念,而是有具体的实现,这个实现其实是个对象,这个对象也有个名字叫做variable object,称为上下文变量, 上下文变量存储的是上下文变量所处执行环境里定义的所有的变量和函数。

全局执行环境的上下文变量是可以访问到的,它就是window对象,所以我们说window能代表全局作用域是有道理的,但是局部作用域即函数的执行环境里的上下文变量是代码不能访问到的,不过javascript引擎在处理数据时候会使用到它。

在javascript语言里还有一个概念,它的名字叫做execution context stack,就是执行环境栈,每个要被执行的函数都会先把函数的执行环境压入到执行环境栈里,函数执行完毕后,这个函数的执行环境就会被执行环境栈弹出,例如上面的例子:函数执行时候函数的执行环境会被压入到执行环境栈里,函数执行完毕,执行环境栈会把这个环境弹出,执行环境栈的控制权就会交由全局环境,如果函数后面还有代码,那么代码就是接着执行。如果函数里嵌套了函数,那么嵌套函数执行完毕后,执行环境栈的控制权就交由了外部函数,然后依次类推,最后就是全局执行环境了。

讲到这里我们大名鼎鼎的作用域链要登场了,函数的执行环境被压入到执行环境栈里后,函数就要执行了,函数执行的第一步不是执行函数里的第一行代码而是在上下文变量里构造一个作用域链,作用域链的英文名字叫做scope chain,作用域链的作用是保证执行环境里有权访问的变量和函数是有序的,这个概念里有两个关键意思:有权访问和有序,我们看看下面的代码:

var b1 = 'b1';
function ftn1(){

  var b2 = 'b2';
  var b1 = 'bbb';

  function ftn2(){
    var b3 = 'b3';
    b2 = b1;
    b1 = b3;

    console.log('b1:'+ b1 +';b2:' + b2 +';b3' + b3); 
    // b1:b3; b2:bbb; b3:b3
  }
  
  ftn2();
}

ftn1();
console.log(b1);

这个例子我们发现,ftn2函数可以访问变量b1,b2,这个体现了有权访问的概念,当ftn1作用域里改变了b1的值并且把b1变量重新定义为ftn1的局部变量,那么ftn2访问到的b1就是ftn1的,ftn2访问到b1后就不会在全局作用域里查找b1了,这个体现了有序性。

广大程序员对作用域链的理解有两块一块是作用域,而作用域在javascript语言里指的是执行环境execution context,执行环境在javascript引擎里是通过上下文变量体现的variable object,javascript引擎里还有一个概念就是执行环境栈execution context stack,当某一个函数的执行环境压入到了执行环境栈里,这个时候就会在上下文变量里构造一个对象,这个对象就是作用域链scope chain,而这个作用域链就是广大程序员理解的第二块知识,作用域链的作用是保证执行环境里有权访问的变量和函数是有序的,作用域链的变量只能向上访问,变量访问到window对象即被终止,作用域链向下访问变量是不被允许的。

很多人常常认为作用域链是理解this指针的关键,这个理解是不正确的,this指针构造是和作用域链同时发生的,也就是说在上下文变量构造作用域链的同时还会构造出一个this对象,this对象是属于上下文变量,而this变量的值就是当前执行环境外部的上下文变量的一份拷贝,这份拷贝里没有作用域链变量的

function show () {
  alert(this);
  function show2 () {
    alert(this);
  }
  show2();
}
show();

我们看到函数show 和 show2里的shis指针都是指向window,这是为什么了?因为在JavaScript我们定义函数方式是通过function xxx() {}形式,那么这个函数不管定义在哪里(包括匿名函数),它都是属于全局对象window,所以他们的执行环境的外部的执行上下文都是指向window。

var a = 10;
function test(){
  a = 100;
  alert(a);
  alert(this.a);
  var a;
  alert(a);
} 
test();
//正确答案:100 10 100
var a = 100;
function test(){
  alert(a);
  var a = 10;
  alert(a);
}
test();
//正确答案: undefined 10
var a = 100;
function test(){
  alert(a);
  a = 10;
  alert(a);
}
test();
alert(a);
//正确答案:100 10 10;

参考文献:http://www.cnblogs.com/sharpxiajun/p/4133984.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,569评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,499评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,271评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,087评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,474评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,670评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,911评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,636评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,397评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,607评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,093评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,418评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,074评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,092评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,865评论 0 196
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,726评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,627评论 2 270

推荐阅读更多精彩内容