Javascript中的局部变量、全局变量的详解与var、let的使用区别
前言
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_var1
var test_var1 = "变量1";
//定义函数testFun
function testFun(){
//在函数中定义变量没加任何关键字的变量test_var2
test_var2 = "变量2";
//函数内使用var关键字定义的test_var3
var 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_var
var test_var = "函数体外的变量";
//定义函数testFun
function testFun(){
//函数内使用var关键字声明变量test_var
var test_var = "函数体内的变量";
//弹窗弹出test_var
alert(test_var);
}
//函数执行
testFun();
alert(test_var);
</script>
打开该文件,会弹出两次弹窗,分别是:

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

在函数体外定义的全局变量test_var,但是在函数体内又定义了局部变量test_var ,在函数中弹出的test_var是函数体内的局部变量覆盖函数体外的全局变量的结果,当离开函数后,局部变量失效,将会看到全局变量。
JavaScript中的变量有块范围吗?
在Java、C、C++等语言中,在 if块 ,循环块中定义的变量,出了该块之后将,不能继续访问。那JavaScript中是否也如此呢?
我们建立一个文件test3.html,从中输入以下代码:
<script type="text/javascript">
//定义函数testFun
function testFun(){
//函数内使用var关键字声明变量test_var
var test_var1 = "1";
//if代码块
if(test_var1 == "1"){
//定义变量test_var2
var test_var2 = 10;
//for代码块
for(var i = 0; i < 5; i++){
//打印输出i
document.write(i);
}
}
//在if块外访问test_var2
alert(test_var2);
//在循环体外访问i
alert(i);
}
//函数执行
testFun();
</script>
我们可以看到两个弹窗:


并且能看到页面上的输出

由此我们可以知道:
在函数体内中的 if 块和循环体内定义的变量,在函数内都是可以访问的。
变量提升
前面介绍中已经知道:局部变量和全局变量同名时,局部变量会覆盖全局变量。
我们定义test4.html,输入以下代码:
<script type="text/javascript">
//在函数外使用var关键字声明变量test_var
var test_var = "函数外的test_var";
//定义函数testFun
function testFun(){
//打印输出test_var
document.writeln(test_var + "<br>");
//函数内使用var关键字定义的test_var
var test_var = "函数内的test_var";
//再次打印输出test_var
document.writeln(test_var + "<br>");
}
//函数执行
testFun();
</script>
输出如下:

在输出全局变量时,居然输出的是underfined,这是什么情况呢?
这便是JavaScript的变量提升机制起了”作用“。下面介绍一下变量提升:
在函数体内变量声明总会被解释器”提升“到函数体的顶部,
那么上面的代码,会变成如下情况:
<script type="text/javascript">
//在函数外使用var关键字声明变量test_var
var test_var = "函数外的test_var";
//定义函数testFun
function testFun(){
//声明被提升到顶部,但是未被赋值
var test_var;
//打印输出test_var
document.writeln(test_var + "<br>");
//给test_var赋值
test_var = "函数内的test_var";
//再次打印输出test_var
document.writeln(test_var + "<br>");
}
//函数执行
testFun();
</script>
由此可见,变量提升只提升声明部分,不提示赋值部分。
我们定义test5.html,输入以下代码:
<script type="text/javascript">
//在函数外使用var关键字声明变量test_var1
var test_var1 = "函数外的test_var1";
//在函数外使用var关键字声明变量test_var2
var test_var2 = "函数外的test_var2";
//定义函数testFun
function testFun(){
//打印输出test_var1
document.writeln(test_var1 + "<br>");
//打印输出test_var2
document.writeln(test_var2 + "<br>");
//for循环的条件为假不会被执行
for(;-1>5;){
//在函数内使用var关键字声明变量test_var1
var test_var1 = "函数内的test_var1";
}
return;
//return后面的语句不会被执行
//在函数内使用var关键字声明变量test_var2
var test_var2 = "函数内的test_var2";
}
//函数执行
testFun();
</script>
输出如下:

在函数内的test_var1 和test_var2 的变量定义根本不会被执行,为何还是输出undefined呢?
这也是变量提升起的”作用“。
let关键字定义变量
从前面我们可以看到,var定义的变量没有块作用域,还有变量提升机制,为了克服这些问题,便引入了let关键字。
我们定义test6.html,输入以下代码:
<script type="text/javascript">
//循环体
for(let v = 0;v < 5;v++){
//在循环体内输出v
console.log(v);
}
//在循环体外输出v
console.log(v);
</script>
按F12,打开console,看到输出如下:

可以看到在循环体外不能访问循环体内定义的变量。
我们定义test7.html,输入以下代码:
<script type="text/javascript">
//在函数外使用let关键字声明变量test_var
let test_var = "函数外的test_var";
//定义函数testFun
function testFun(){
//打印输出test_var
console.log(test_var);
//在函数内使用let关键字声明变量test_var
let test_var = "函数内的test_var"
//打印输出test_var
console.log(test_var);
}
//函数执行
testFun();
</script>
按F12,打开console,看到输出如下:

这是因为函数内有和全局变量同名的局部变量,会覆盖掉全局变量,但是let关键字声明的变量并没有提升机制,所以会报错。
小结
本文介绍了JavaScript中的局部变量和全局变量的知识和var,let声明变量的区别。给我们的启示是如果浏览器支持let关键字,那么就尽量用let来避免变量提升机制等情况。
欢迎关注
扫下方二维码即可关注,微信公众号:code随笔

Javascript中的局部变量、全局变量的详解与var、let的使用区别的更多相关文章
- JavaScript中的鼠标滚轮事件详解
JavaScript中的鼠标滚轮事件详解/*Firefox注册事件*/ ~~~Firefox: addEventListener('DOMMouseScroll', handler, false)if ...
- JavaScript中typeof和instanceof深入详解
这次主要说说javascript的类型判断函数typeof和判断构造函数原型instanceof的用法和注意的地方. typeof 先来说说typeof吧.首先需要注意的是,typeof方法返回一个字 ...
- JavaScript 中 apply 、call 的详解
apply 和 call 的区别 ECMAScript 规范给所有函数都定义了 call 与 apply 两个方法,它们的应用非常广泛,它们的作用也是一模一样,只是传参的形式有区别而已. 原文作者:林 ...
- Javascript中的this关键字用法详解
在javascript里面,this是一个特殊的对象,它不像其他编程语言那样,是存储在实例中的值,直接指向此实例. 而是作为一个单独的指针,在不同的情况之下,指向不同的位置,这也是为什么我们会将它搞混 ...
- JavaScript中事件委托(事件代理)详解
在JavaScript的事件中,存在事件委托(事件代理),那么什么是事件委托呢? 事件委托在生活中的例子: 有三个同事预计会在周一收到快递.为签收快递,有两种办法:一是三个人在公司门口等快递:二是委托 ...
- javascript中6种基本数据类型详解
javascript中有5中数据类型(也称为基本数据类型):Undefined.Null.Boolean.Number和String,还有一种复杂数据类型——object,object本质是由一组键值 ...
- JavaScript中继承的实现方法--详解
最近看<JavaScript王者归来>中关于实现继承的方法,做了一些小总结: JavaScript中要实现继承,其实就是实现三层含义:1.子类的实例可以共享父类的方法:2.子类可以覆盖父类 ...
- JavaScript中定义类的方式详解
本文实例讲述了JavaScript中定义类的方式.分享给大家供大家参考,具体如下: Javascript本身并不支持面向对象,它没有访问控制符,它没有定义类的关键字class,它没有支持继承的exte ...
- Javascript中的apply与call详解
JavaScript中有一个call和apply方法,其作用基本相同,但也有略微的区别. 一.方法定义 1.call 方法 语法:call([thisObj[,arg1[, arg2[, [,.arg ...
随机推荐
- 金蝶cloud成本核算流程
- Nginx模块-ngx_http_mirror_module-流量复制
参考1:https://www.cnblogs.com/cjsblog/p/12163207.html Nginx流量复制 需求 将生产环境的流量拷贝到预上线环境或测试环境,这样做有很多好处,比如: ...
- play framework在eclipse中自动的预编译生成precompiled文件
一.修改 eclipe 中的启动文件属性eclipse/*.launch 中的最后一条:加入参数 -Dprecompile=yes 将会在启动项目时,进行项目的预编译 (将在项目中生成 precom ...
- Java操作redis客户端Jedis连接集群(Cluster)
创建JedisCluster类连接redis集群. @Test public void testJedisCluster() throws Exception { //创建一连接,JedisClust ...
- xcode7 上传APPStore错误ERROR ITMS-90474: iPad Multitasking support requires these orientations
在使用Xcode7 上传AppStore时候发现ERROR ITMS-90474错误.报错描述如下: ERROR ITMS-90474: “Invalid Bundle. iPad Multitask ...
- [Algo] 281. Remove Spaces
Given a string, remove all leading/trailing/duplicated empty spaces. Assumptions: The given string i ...
- ununtu 16.04 下的 VsCode 下载与安装
Vscode发现用包下载显示找不到网页,于是只有继续折腾. 折腾如下: ubuntu-desktop You can update your system with unsupported packa ...
- scala编程(五)——基本类型和操作
文本 文本是直接在代码里写常量值的一种方式以.在Scala中并不显式的使用Int或float,而是以文本的方式写成 val 变量. 如果整数文本结束于 L 或者 l,就是 Long 类型,否则就是 I ...
- javascript 获取 sx:datetimepicker 的值
<div align="center"><sx:datetimepicker label="Start_Time" id="S ...
- Fiddler发送get post测试 笔记
0 环境 系统环境:win7 1 操作 1 post 类似 2 get