2
3
4
5
6
7
8
9
10
<script type="text/javascript">
var a = 1;
function hehe()
{
         window.alert(a);
         var a = 2;
         window.alert(a);
}
hehe();
</script>

  

执行结果如下所示:

第一个alert:

第二个alert:

这是一个令人诧异的结果,为什么第一个弹出框显示的是undefined,而不是1呢?

一个页面里直接定义在script标签下的变量是全局变量即属于window对象的变量,按照javascript作用域链的原理,当一个变量在当前作用域下找不到该变量的定义,那么javascript引擎就会沿着作用域链往上找直到在全局作用域里查找。

首先这段程序涉及到了以下三个概念 执行环境、变量对象、 作用域链、 js的执行环境分全局的(浏览器的话就是window执行环境)和function执行环境,变量对象是用来保存执行环境下的变量和方法的,而作用域链上放着一个一个的变量对象形成一个链条。 这段代码的执行过程应该是这样的 首先进入全局执行环境 建立该执行环境下的变量对象A(保存有该执行环境下的x和一个匿名方法),再往下执行到匿名方法的执行环境 建立变量对象B(保存有该执行环境下的x),而js的当前执行环境的变量对象永远放在作用域链的最前端,所在执行第一个alert(x), 就会找当前执行环境的变量对象B是否保存有x, 而事实上是有的,但alert(x)之前没有给x赋值,所出得到的结果就是undefined, 如果变量对象B中不存在x,那么程序就会顺着作用域链找上一个变量对象A里是否有x.

js的变量有两种作用域:全局变量和局部变量。没有使用 var 声明的变量和在function之外声明的变量都是全局变量,是window属性之一;使用 var 声明的变量属于所在函数,不管在函数的哪个位置出现,等价于在函数一开始声明。局部变量比同名全局变量的优先级高,所以局部变量会隐藏同名的全局变量。要想访问被隐藏的全局变量就加上 window. 前缀。
js没有块作用域,在语句块之后,在函数结束之前,语句块定义的变量都是可以访问的。比如:for(var idx =0; idx<2;idx++){} alert(idx); 结果显示为2。

上段代码相当于

1
2
3
4
5
6
7
var x=1;
function (){
var x;
alert(x);
 x=1212;
alert(x);
}

正确代码:第一次要this.x

1
2
3
 
 
 
 
 
 
 
4
5
6
7
8
9
10
<script type="text/javascript">
var a = 1;
function hehe()
{
         window.alert(this.a);
         var a = 2;
         window.alert(a);
}
hehe();
</script>

js中全局和局部变量的区别的更多相关文章

  1. iOS中 static变量与全局、局部变量的区别 !

    static变量与全局.局部变量的区别 全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量.全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式. 这两者在存储方式上并 ...

  2. PHP和JS中全局变量和局部变量

    一,PHP中全局变量和局部变量 php与C++中对全局变量和局部变量定义类似,全局变量:函数外定义的变量,在全局通用:局部变量:在函数内定义的变量,只在函数内有效.PHP中变量范围跨越了include ...

  3. js中全局变量和局部变量以及变量声明提升

    javascript中全局变量和局部变量的区别 转载前端小99 发布于2018-04-23 15:31:35 阅读数 2102  收藏 展开 [javascript] view plain copy ...

  4. java之static变量与全局、局部变量的区别

    static变量与全局.局部变量的区别 全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量.全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式.这两者在存储方式上并无 ...

  5. 浅谈JS中的!=、== 、!==、===的用法和区别 JS中Null与Undefined的区别 读取XML文件 获取路径的方式 C#中Cookie,Session,Application的用法与区别? c#反射 抽象工厂

    浅谈JS中的!=.== .!==.===的用法和区别   var num = 1;     var str = '1';     var test = 1;     test == num  //tr ...

  6. JS中isPrototypeOf 和hasOwnProperty 的区别 ------- js使用in和hasOwnProperty获取对象属性的区别

    JS中isPrototypeOf 和hasOwnProperty 的区别 1.isPrototypeOf isPrototypeOf是用来判断指定对象object1是否存在于另一个对象object2的 ...

  7. (网页)Angular.js 中 copy 赋值与 = 赋值 区别

    转自st.gg Angular.js 中 copy 赋值与 = 赋值 区别 为什么用 $scope.user = $scope.master; $scope.master 会跟着 $scope.use ...

  8. js中的substr和substring区别

    js中的substr和substring区别 Substring: 该方法可以有一个参数也可以有两个参数. (1)  一个参数: 示例: var str=“Olive”: str.substring( ...

  9. JS 中的require 和 import 区别整理

    ES6标准发布后,module成为标准,标准的使用是以export指令导出接口,以import引入模块,但是在我们一贯的node模块中,我们采用的是CommonJS规范,使用require引入模块,使 ...

随机推荐

  1. python自动化适应多接口的断言怎么做?

    最近做的接口自动化,遇到了很多模块的接口,返回的断言不太相同,在放在unnitest单元测试框架+ddt数据驱动,做参数时,发现不能只通过一个方式进行断言,那么,要怎么做才能做到适配当前所有接口的断言 ...

  2. MongoDB_安装、配置、连接(五)

    MongoDB 是跨平台的,既可以在 Linux系统下安装,也可以在Windows 系统.MacOS系统下安装,本节主要介绍如何在 Linux 系统下安装 MongoDB. windows安装:htt ...

  3. spring5无法在控制台打印日志的原因

    想要在控制台输出spring的日志,却无法输出,log4j2所需要的jar文件都已经导入,log4j2的配置文件也存在,调整日志级别也不行,一通百度后发现是缺少spring的jcl的jar文件,把sp ...

  4. 关于less使用初学者常犯错误

    1.多层嵌套 2.定义变量复用性不高 3.方法定义多余参数.

  5. test_6 python的列表去重

    1.使用内置函数set() set() 函数创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算交集.差集.并集等. 2.创建一个空的列表进行比较,把不重复的元素添加到新的列表中 #co ...

  6. SparkSQL学习笔记

    概述 冠状病毒来临,宅在家中给国家做贡献之际,写一篇随笔记录SparkSQL的学习笔记,目的有二,一是记录整理之前的知识作为备忘录,二是分享技术,大家共同进步,有问题也希望大家不吝赐教.总体而言,大数 ...

  7. EF4中多表关联查询Include的写法

    大家好,好久没有写作了,最近遇到了个问题,最终是靠自己的尝试写出来的,希望可以帮到有需要的人. 在我们查询时通常会遇到多级表关联的情况,很多时候有人会想写一个from LINQ语句来解决,那么冗长的代 ...

  8. 记一次异步处理导致Jetty Request对象泄漏

    最近排查一个bug,发现了一系列有意思的东西,对「自定义线程池」.「Jetty线程模型」都有了一些新的认识. 本文预计阅读时间10分钟,包括: 问题表现 常见原因筛查 根因与源码分析 最佳实践 一些小 ...

  9. elasticsearch拼写纠错之Term Suggester

    一.什么是拼写纠错 拼写纠错就是搜索引擎可以智能的感知用户输入关键字的错误,并使用纠正过的关键字进行搜索展示给用户:拼写纠错是一种改善用户体验的功能: elasticsearch提供了以下不同类型的s ...

  10. MySQL 5.7 版本的 UTF8 字符集调研

    一.故事背景 记一次 sql_mode 非严格模式下的业务事故排查.当时数据库没有开启 sql_mode 为严格模式,并且数据表的编码是 utf8,表现为业务侧的 Insert SQL 语句执行成功, ...