当前位置: 首页 > news >正文

作用域与作用域链

 

javascript是一种过程式编程的脚本语言,对于过程式编程来说,代码执行的时间与数据标识的空间是不可分割的,我们只有把指令执行的具体时刻与标识映射的具体地址结合起来,才能确定程序在执行瞬间的上下文状态。于是,代码时刻和数据标识的结构就形成了javascript作用域的概念。javascript中对作用域的定义是变量存在的执行环境,而在这里还包含了代码执行的时刻,即两者的结合。

在一个作用域中的上下文状态,在另一个作用域来说是不适用的。

任何一个程序都会在一个原始的环境中开始运行,这个原始的环境被称为全局环境。全局环境中包含了一些预定义的元素,这些元素对于我们的程序来说是自然存在的,它们本来就在那里,我们拿来即可使用。

在javascript里的全局环境就是一个对象,这个对象是javascript运行环境的根。对于浏览器中的javascript来说,这个根就是window对象;对于全局环境中的javascript语句,window对象就是当前的作用域。

在全局环境中,当我们写下: var color = "red"; 这就相当于在window作用域中定义了一个变量color,并为它赋值为red ,但是当我们在全局环境中写下: color = "red"; 这就相当于我们为window对象定义了一个属性color,且color属性的值为red,在全局环境里,window作用域的一个变量color和window对象的一个属性几乎是等价的;如果是在函数体内部的语句,那就完全不一样了。例如:

<script type="text/javascript">

var color = "red";

mycolor = "green";

alert( color + "and" + mycolor);  //  red and green

changecolor();  //  调用函数

function changecolor(){

  alert( "The apple is" + color);  // The apple is undefined

  alert( "The tree is green" + mycolor);   // The tree is green 

  var color = "bule";

  mycolor = "pink";

  alert(color);  //blue

  alert(mycolor)  //pink

}

alert( color + "and" + mycolor);  //red and pink

</script>

从例子可以看出,使用var定义的变量在全局环境中和函数体内部是完全不一样的两个东西。所以,我们只需要记住:var定义的是作用域中的一个变量,而没有var的标识符可能是全局根对象的一个属性。当代码运行在全局作用域时,作用域的根对象就是window,所以在全局执行环境时有没有var都无所谓。

  当代码运行进入一个函数的时,javascript会创建一个新的作用域,来作为当前作用域的子作用域。然后将当前全局作用域切换为这个新建的子作用域,开始执行函数逻辑。

在第一步预编译分析中,javascript执行引擎将所有定义式函数直接创建为作用域上的函数变量,并将其值初始化为定义的函数代码逻辑,也就是为其建立了可调用的函数变量。而对于所有var定义的变量,也会在第一步的预编译中创建起来,并将初始值设为undefined。

  随后,javascript开始解释执行代码。当遇到对函数名和变量名的使用时,javascript执行引擎会首先在当前作用域中查找函数或变量,如果没有就到上层作用域中查找。因此,前面的语句引用后面语句定义的var变量时,该变量其实已经存在,只是初始值为undefined。

  所以说,用var定义的变量只对本作用域有效,尽管上层作用域中有同名的东西,都与本作用域中的var变量无关。推出本作用域之后,回到原来的作用域中该是什么就是什么。

  其实,函数在每次调用的时候都会产生一个子作用域,推出函数时,这个子作用域就会消失,下次调用相同函数时有是另一个子作用域了。在运行的函数内部再调用另外的函数时,有产生另一个作用域,这样随着函数调用的深入就会形成作用域链,在插找变量的时候,搜索机制就会沿着作用域链一层一层向上搜索。

  像上面的例子中,作用域链就是changecolor()对象、全局的window对象。

如果changecolor函数内部没有 var color = "blue";这条语句,那么当我们使用color变量时,就会沿着作用域链向上查找color变量,这是会返回red而不是undefined。但是我们在函数内部使用var定义了color变量,且在alert()方法后面,这是函数内部的作用域中color变量已经存在,这是初始化值为undefined。

 

转载于:https://www.cnblogs.com/lugefan/p/6518754.html

相关文章:

  • 批量修改SQL数据库字段值
  • [C#7] 1.Tuples(元组)
  • flex z-order错误解决
  • css居中小结
  • Flex的DataGrid中时间如何格式化
  • 买卖股票最佳时机
  • parentApplication 和parentDocument 的区别
  • C#设计模式(11)——外观模式
  • flex大小写转化
  • Target runtime Apache Tomcat 5.5 is not defined
  • Android耗时操作
  • hibernate自定义主键
  • 2017.3.9 组合数学学习——组合、多重集排列
  • Flex:PopUpManager的createPopUp与addPopUp区别
  • HTTP协议返回状态码
  • canvas 高仿 Apple Watch 表盘
  • go append函数以及写入
  • JS正则表达式精简教程(JavaScript RegExp 对象)
  • leetcode98. Validate Binary Search Tree
  • opencv python Meanshift 和 Camshift
  • PHP的类修饰符与访问修饰符
  • Sass Day-01
  • Spring Cloud Feign的两种使用姿势
  • SpringBoot 实战 (三) | 配置文件详解
  • 猫头鹰的深夜翻译:JDK9 NotNullOrElse方法
  • 悄悄地说一个bug
  • 世界上最简单的无等待算法(getAndIncrement)
  • 算法-插入排序
  • 突破自己的技术思维
  • 微服务核心架构梳理
  • 微信开源mars源码分析1—上层samples分析
  • 用 Swift 编写面向协议的视图
  • 运行时添加log4j2的appender
  • MiKTeX could not find the script engine ‘perl.exe‘ which is required to execute ‘latexmk‘.
  • 我们雇佣了一只大猴子...
  • # 睡眠3秒_床上这样睡觉的人,睡眠质量多半不好
  • #我与Java虚拟机的故事#连载06:收获颇多的经典之作
  • (20050108)又读《平凡的世界》
  • (NO.00004)iOS实现打砖块游戏(九):游戏中小球与反弹棒的碰撞
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理第3章 信息系统治理(一)
  • (一)appium-desktop定位元素原理
  • (一)UDP基本编程步骤
  • (转) RFS+AutoItLibrary测试web对话框
  • (转)MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在
  • (转)Mysql的优化设置
  • (转)大型网站架构演变和知识体系
  • (转)德国人的记事本
  • (转)拼包函数及网络封包的异常处理(含代码)
  • (总结)Linux下的暴力密码在线破解工具Hydra详解
  • .NET C# 使用 SetWindowsHookEx 监听鼠标或键盘消息以及此方法的坑
  • .net core 3.0 linux,.NET Core 3.0 的新增功能
  • .net6Api后台+uniapp导出Excel
  • .net安装_还在用第三方安装.NET?Win10自带.NET3.5安装
  • .NET面试题(二)
  • .Net面试题4