前言

Javascript中的变量定义方式有以下三种方式: 1、直接定义变量,var与let均不写;

a = 10;

2、使用var关键字定义变量

var a = 10;

3、使用let关键字定义变量

let a = 10;

这三种方式有什么区别呢? JavaScript全局变量和局部变量又是什么呢? 可以带着这两个问题往下看。

变量的作用域

变量是有作用域的,大多数语言中的变量的作用域都有全局变量和局部变量之分。 首先我们建立一个文件test1.html,从中输入以下代码:

<script type="text/javascript">//在函数外使用var关键字声明变量test_var1var test_var1 = "变量1";//定义函数testFunfunction testFun(){//在函数中定义变量没加任何关键字的变量test_var2test_var2 = "变量2";//函数内使用var关键字定义的test_var3var test_var3 = "变量3";}//函数执行testFun();alert(test_var1 + "n" + test_var2);alert(test_var3);
</script>

在浏览器打开我们的html页面,可以看到只弹出了一个弹窗:

第二个弹窗为什么没有成功弹出呢? 我们按F12,看一下报错内容:

由此可以看出 test_var3 在函数执行后是没有被定义的。说明在函数体内用 var 关键字声明的变量 test_var3 是局部变量; 在函数体外使用 var 关键字定义的变量test_var1 和在函数体内未用任何关键字定义的变量 test_var2 是全局变量。

得出结论: 在函数体外使用var关键字定义的变量和在函数体内未用任何关键字声明的变量是全局变量,在函数体内使用var关键字声明的变量是局部变量。

var声明的全局变量和局部变量同名

我们建立一个文件test2.html,从中输入以下代码:

<script type="text/javascript">//在函数外使用var关键字声明变量test_varvar test_var = "函数体外的变量";//定义函数testFunfunction testFun(){//函数内使用var关键字声明变量test_varvar test_var = "函数体内的变量";//弹窗弹出test_varalert(test_var);}//函数执行testFun();alert(test_var);
</script>

打开该文件,会弹出两次弹窗,分别是:

点击确定后还会弹窗一次:

在函数体外定义的全局变量test_var,但是在函数体内又定义了局部变量test_var ,在函数中弹出的test_var是函数体内的局部变量覆盖函数体外的全局变量的结果,当离开函数后,局部变量失效,将会看到全局变量。

JavaScript中的变量有块范围吗?

JavaCC++等语言中,在 if块 ,循环块中定义的变量,出了该块之后将,不能继续访问。那JavaScript中是否也如此呢?

我们建立一个文件test3.html,从中输入以下代码:

<script type="text/javascript">//定义函数testFunfunction testFun(){//函数内使用var关键字声明变量test_varvar test_var1 = "1";//if代码块if(test_var1 == "1"){//定义变量test_var2var test_var2 = 10;//for代码块for(var i = 0; i < 5; i++){//打印输出idocument.write(i);}}//在if块外访问test_var2alert(test_var2);//在循环体外访问ialert(i);}//函数执行testFun();
</script>

我们可以看到两个弹窗:

并且能看到页面上的输出

由此我们可以知道: 在函数体内中的 if 块和循环体内定义的变量,在函数内都是可以访问的。

变量提升

前面介绍中已经知道:局部变量和全局变量同名时,局部变量会覆盖全局变量。 我们定义test4.html,输入以下代码:

<script type="text/javascript">//在函数外使用var关键字声明变量test_varvar test_var = "函数外的test_var";//定义函数testFunfunction testFun(){//打印输出test_vardocument.writeln(test_var + "<br>");//函数内使用var关键字定义的test_varvar test_var = "函数内的test_var";//再次打印输出test_vardocument.writeln(test_var + "<br>");}//函数执行testFun();
</script>

输出如下:

在输出全局变量时,居然输出的是underfined,这是什么情况呢? 这便是JavaScript的变量提升机制起了”作用“。下面介绍一下变量提升: 在函数体内变量声明总会被解释器”提升“到函数体的顶部, 那么上面的代码,会变成如下情况:

<script type="text/javascript">//在函数外使用var关键字声明变量test_varvar test_var = "函数外的test_var";//定义函数testFunfunction testFun(){//声明被提升到顶部,但是未被赋值var test_var;//打印输出test_vardocument.writeln(test_var + "<br>");//给test_var赋值test_var = "函数内的test_var";//再次打印输出test_vardocument.writeln(test_var + "<br>");}//函数执行testFun();
</script>

由此可见,变量提升只提升声明部分,不提示赋值部分。

我们定义test5.html,输入以下代码:

<script type="text/javascript">//在函数外使用var关键字声明变量test_var1var test_var1 = "函数外的test_var1";//在函数外使用var关键字声明变量test_var2var test_var2 = "函数外的test_var2";//定义函数testFunfunction testFun(){//打印输出test_var1document.writeln(test_var1 + "<br>");//打印输出test_var2document.writeln(test_var2 + "<br>");//for循环的条件为假不会被执行for(;-1>5;){//在函数内使用var关键字声明变量test_var1var test_var1 = "函数内的test_var1";}return;//return后面的语句不会被执行//在函数内使用var关键字声明变量test_var2var test_var2 = "函数内的test_var2";}//函数执行testFun();
</script>

输出如下:

在函数内的test_var1test_var2 的变量定义根本不会被执行,为何还是输出undefined呢? 这也是变量提升起的”作用“。

let关键字定义变量

从前面我们可以看到,var定义的变量没有块作用域,还有变量提升机制,为了克服这些问题,便引入了let关键字。

我们定义test6.html,输入以下代码:

<script type="text/javascript">//循环体for(let v = 0;v < 5;v++){//在循环体内输出vconsole.log(v);}//在循环体外输出vconsole.log(v);
</script>

按F12,打开console,看到输出如下:

可以看到在循环体外不能访问循环体内定义的变量。

我们定义test7.html,输入以下代码:

<script type="text/javascript">//在函数外使用let关键字声明变量test_varlet test_var = "函数外的test_var";//定义函数testFunfunction testFun(){//打印输出test_varconsole.log(test_var);//在函数内使用let关键字声明变量test_varlet test_var = "函数内的test_var"//打印输出test_varconsole.log(test_var);   }//函数执行testFun();
</script>

按F12,打开console,看到输出如下:

这是因为函数内有和全局变量同名的局部变量,会覆盖掉全局变量,但是let关键字声明的变量并没有提升机制,所以会报错。

小结

本文介绍了JavaScript中的局部变量和全局变量的知识和var,let声明变量的区别。给我们的启示是如果浏览器支持let关键字,那么就尽量用let来避免变量提升机制等情况。

欢迎关注

扫下方二维码即可关注,微信公众号:code随笔

http://weixin.qq.com/r/XSh7YwTEzFmzrUAA931P (二维码自动识别)

java 全局变量_Javascript中的局部变量、全局变量的详解与var、let的使用区别相关推荐

  1. php 递归中的全局变量,PHP中递归的实现实例详解

    递归的定义 递归(http:/en.wikipedia.org/wiki/Recursive)是一种函数调用自身(直接或间接)的一种机制,这种强大的思想可以把某些复杂的概念变得极为简单.在计算机科学之 ...

  2. java jxl mergecells_java 中JXL操作Excel实例详解

    JXL操作Excel 前言: jxl是一个韩国人写的java操作excel的工具, 在开源世界中,有两套比较有影响的API可 供使用,一个是POI,一个是jExcelAPI.其中功能相对POI比较弱一 ...

  3. Java中Lambda表达式使用及详解

    Java中Lambda表达式使用及详解 前言 一.Lambda表达式的简介 Lambda表达式(闭包):java8的新特性,lambda运行将函数作为一个方法的参数,也就是函数作为参数传递到方法中.使 ...

  4. java 静态 编译_Java中的动态和静态编译实例详解

    Java中的动态和静态编译实例详解 首先,我们来说说动态和静态编译的问题. Q: java和javascript有什么区别? 总结了一下:有以下几点吧: 1.首先从运行环境来说java代码是在JVM上 ...

  5. Java中的异常和处理详解

    Java中的异常和处理详解 参考文章: (1)Java中的异常和处理详解 (2)https://www.cnblogs.com/lulipro/p/7504267.html 备忘一下.

  6. java web json_java web中对json的使用详解

    一.在Java Web的开发过程中,如果希望调用Java对象转化成JSON对象等操作.则需要引入以下jar包,不然运行时则报错. 1.commons-beanutils.jar 2.commons-c ...

  7. java map中的entry_java中Map及Map.Entry详解(组图)

    java中Map及Map.Entry详解(组图) 08-22栏目:技术 TAG:map.entry map.entry Map是java中的接口,Map.Entry是Map的一个内部接口. copyr ...

  8. java中迭代器要导包吗_java 中迭代器的使用方法详解

    java 中迭代器的使用方法详解 前言: 迭代器模式将一个集合给封装起来,主要是为用户提供了一种遍历其内部元素的方式.迭代器模式有两个优点:①提供给用户一个遍历的方式,而没有暴露其内部实现细节:②把元 ...

  9. java bip-39_Java中对XML的解析详解

    先简单说下前三种方式: DOM方式:个人理解类似.net的XmlDocument,解析的时候效率不高,占用内存,不适合大XML的解析: SAX方式:基于事件的解析,当解析到xml的某个部分的时候,会触 ...

最新文章

  1. MySQL 学习笔记(12)— 数据类型(定长字符、变长字符、字符串大对象、数字类型、日期时间类型、二进制类型)
  2. 3、如何证明static静态变量和类无关?
  3. 【 C 】assert.h 简明介绍
  4. 《C++ primer》--第10章
  5. idea连接mysql
  6. WebRTC十周年、Space X成功对接国际空间站、TikTok复制品Zynn或有快手支持|Decode the Week...
  7. Java 非阻塞 IO 和异步 IO
  8. huffman编码的程序流程图_Huffman编码实现压缩解压缩
  9. Oracle SQL Loader数据导入
  10. CStdioFile写文件中出现的问题
  11. Linux -lvm -扩容、缩容逻辑卷(针对xfs)
  12. MCU远程升级方案,可解决升级错误死机问题
  13. VXLAN技术产生背景
  14. 假设检验与常见的统计检验方法
  15. ​模拟人生3 Mac版自由性超高的模拟游戏
  16. matlab的基本函数,matlab基本函数
  17. 【激光SLAM, ROS】激光畸变的校正
  18. Day527528529.图灵学院之面试题③ -面经
  19. 数学专业的数学与计算机专业的数学的比较(转)
  20. Git 撤销已提交的文件

热门文章

  1. python实现自动发送微博,当自己写博客时同步上去。
  2. Python编程基础:第十三节 循环控制语句Loop Control Statements
  3. 华为开源深度学习框架MindSpore背后的商业野心
  4. 微软NNI-业内最亲民的AutoML工具学习笔记(1):AutoFeatureENG
  5. 【LeetCode从零单排】No 114 Flatten Binary Tree to Linked List
  6. 斯坦福机器学习公开课学习笔记(2)—监督学习 梯度下降
  7. 支付宝架构师眼里的高并发架构
  8. How do annotations work internally--转
  9. solr服务器的查询过程
  10. 改变eclipse工程中代码的层次结构