当前位置: 首页 > 编程笔记 >

Javascript变量的作用域和作用域链详解

戈华茂
2023-03-14
本文向大家介绍Javascript变量的作用域和作用域链详解,包括了Javascript变量的作用域和作用域链详解的使用技巧和注意事项,需要的朋友参考一下

工作这几年,js学的不是很好,正好周末有些闲时间,索性买本《js权威指南》,大名鼎鼎的犀牛书,好好的把js深入的看一看。买过这本书的第一印象就是贼厚,不过后面有一半部分都是参考手册。

一:作用域

  说起变量第一个要说到的肯定就是作用域,正是因为不熟悉JS的作用域,往往就会把面向对象的作用域张冠李戴,毕竟有些东西总是习惯性的这样,但是并不是每次照搬都是可以的,那么下一个问题就来了,js到底是什么作用域,当然是函数作用域了,我们的浏览器就是一个被实例化的window对象,如果在window下定义一个name字段,那么name字段就具有window这个函数作用域,也就是在window下都是可以访问的,如果在window下定义一个function ctrip,然后里面再定义一个name,那么这个新定义的name只能在ctrip函数下通用,而老的name继续在window下通用,举个例子。

从图中可以看出两点:

1: 在window下定义了一个name,居然还可以在function下定义一个重名的name,这个在C#里面是不可想象的。

2:在JS下就可以做到眼瞎,它只认自己的作用域,所以就出现了第一个"second",你可能觉得这个没有什么稀奇的地方,这是因为可能你还没有真正理解什么是函数作用域,解析器在执行ctrip的时候,第一件事情就是寻找ctrip下的所有局部变量,然后再执行后续语句,既然是先寻找,那么var name="second"这条语句定义在ctrip中任何位置都是可以的,下面我们把语句调换过来。

可以看到在ctrip函数下,第一个console.log输出的是undefined,这个结果可以证实,确实做了第一件事情是收集到了name这个局部变量,可能有人说为什么没有变成”second“,那是因为初始化操作必须是逐语句执行,所以在ctrip函数中执行console.log(name)时,此时解析器只知道有一个未赋值的变量name,所以就console的时候就是undefined了。

二:作用域链

  从上面的这个例子中我们也很清楚的知道了,在function中html" target="_blank">定义的变量只具有function范围内的作用域,同时我们也看到上面这个例子只是一层嵌套,window是个大的function,里面是一个ctrip的function,同样的道理也可以延伸到多层嵌套,比如三层,四层。。。。N层,这些层就形成了一个链式结构。

从图中可以看到,我在ctrip下再定义了一个plane函数,这样的话就有三层了,输出的结果也是我们希望看到的,每层的name只在自己的作用域范围

内生效,但是下面有一个问题来了,有一天我傻逼了,在定义plane的函数时,把 var name="third" 中的var忘记写了,那么这个时候,plane中的

name到底是什么值呢? 是first还是second呢?


var name="first";

function ctrip(){

  var name="second";

  function plane(){

     name="third";

     console.log(name);

  }

  plane();

  console.log(name);

}

ctrip();

console.log(name);

现在就是考验你是否真的懂了作用域链,仔细想想会发现,当代码执行到plane函数中的name=”third“时,发现plane函数中并没有name这个局部变量,恰好代码又在ctrip这个大函数中,所以解析器就会回溯到ctrip函数中寻找name,发现果然有name,这个时候就把ctrip的name修改成了”third“。

又有一天,我喝多了酒又傻逼了一回,在定义plane函数的时候,把name="third" 错写成了 nam="third"; 丢了一个e,你可以说是酒精的问题,

又不是我代码的问题。那么这个时候解析器该怎么处理呢?同样的道理,在回溯时,发现ctrip没有,再回溯到顶层的window下,发现还是没有,

这个时候解析器做了这样的处理,既然整个链中都没有,你又赋值了,我总不能给你报错,那多尴尬呀,就索性给你在window下隐式的定义一个

nam变量,这个时候nam其实就是全局变量了。我们可以在window顶层console一下nam看看。

好了,关于变量的东西也就这么多了,没什么稀奇的,理解了就没什么意思了。

 类似资料:
  • 本文向大家介绍详解JavaScript作用域、作用域链和闭包的用法,包括了详解JavaScript作用域、作用域链和闭包的用法的使用技巧和注意事项,需要的朋友参考一下 1. 作用域 作用域是指可访问的变量和函数的集合。 作用域可分为全局作用域和局部作用域。 1.1 全局作用域 全局作用域是指最外层函数外面定义的变量和函数的集合。 换言之,这些最外层函数外面定义的变量和函数在任何地方都能访问。 举个

  • 本文向大家介绍javascript 作用于作用域链的详解,包括了javascript 作用于作用域链的详解的使用技巧和注意事项,需要的朋友参考一下 javascript 作用于作用域链的详解 一、JavaScript作用域 任何程序设计语言都有作用域的概念,简单的说,作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。在JavaScript中,变量的作用域有全局作用域和局

  • 本文向大家介绍JS 作用域与作用域链详解,包括了JS 作用域与作用域链详解的使用技巧和注意事项,需要的朋友参考一下 (1)作用域 一个变量的作用域(scope)是程序源代码中定义的这个变量的区域。 1. 在JS中使用的是词法作用域(lexical scope) 不在任何函数内声明的变量(函数内省略var的也算全局)称作全局变量(global scope) 在函数内声明的变量具有函数作用域(func

  • 本文向大家介绍Python中的变量和作用域详解,包括了Python中的变量和作用域详解的使用技巧和注意事项,需要的朋友参考一下 作用域介绍 python中的作用域分4种情况: L:local,局部作用域,即函数中定义的变量; E:enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的; G:globa,全局变量,就是模块级别定义的变量; B:built-i

  • 本文向大家介绍JavaScript作用域链实例详解,包括了JavaScript作用域链实例详解的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了JavaScript作用域链。分享给大家供大家参考,具体如下: 跟其他语言一样,变量和函数的作用域揭示了这些变量和函数的搜索路径。对于JavaScript而言,理解作用域更加重要,因为在JavaScript中,作用域可以用来确定this的值,并且Ja

  • 变量作用域 变量的作用域值的是变量的生命周期和作用范围(全局与局部作用域的区别)。 作用域介绍 静态作用域 静态作用域有称为词法作用域,即指其在编译的阶段就可以决定变量的引用。静态作用域只更变量定义的位置有关与代码执行的顺序无关。 var x = 0; function foo() { alert(x); } function bar() { var x = 20; foo(); }