搞懂JavaScript全局变量与局部变量,看这篇文章就够了
1.什么是全局变量和局部变量
全局变量:常常定义在函数外部,拥有全局作用域,即在 JavaScript 代码的任何地方都可以访问。
局部变量:定义在函数内部,只能在函数中使用的变量,作用范围是从函数开始到结尾,即在{}里。
在函数内声明的变量只在函数体内有定义,即为局部变量,其作用域是局部性的。需要注意的是,在函数体内声明局部变量时,如果不使用 var 关键字,则将声明全局变量。
<script>
var str1 = "hello1"; //定义一个全局变量
function a() {
var str2 = "hello2"; //定义一个局部变量
str3 = "hello3"; //定义一个全局变量
}
</script>
此处str1和str3是全局变量,str2为局部变量。
2.全局变量和局部变量的声明
2.1 全局变量的声明
在js中全局变量声明方式分为显示声明和隐式声明。
第一种声明方式:使用var关键字+变量名在函数外部声明就是全局变量,例如:
var bianliang = "全局变量";
第二种声明方式:没有使用var关键字声明,直接给变量名赋值,不管是在函数内部还是外部都是全局变量,例如:
<script>
text = "全局变量";
function bl() {
text1 = "我也是全局变量";
var text2 = "我是局部变量";
console.log(text2); //局部变量只能在函数中使用
}
bl() //结果:我是局部变量
console.log(text); //结果:全局变量
console.log(text1); //结果:我也是全局变量
//console.log(text2); //局部变量,在函数外使用会报错
</script>
第三种声明方式:使用window全局对象来声明,全局对象的属性对应也是全局变量,例如:
window.test3 = 'window全局对象声明全局变量';
console.log(test3);//结果:window全局对象声明全局变量
2.2 局部变量的声明
声明局部变量一定要使用var
关键字,使用var
关键字声明变量时,变量会自动添加到距离最近的可用环境中。如果没有写var
, 变量就会暴露在全局上下文中, 成为全局变量。如果变量在未声明的情况下被初始化,该变量会自动添加到全局环境。
<script>
function bl() {
text1 = "我也是全局变量";//没有使用var 为全局变量
var text2 = "我是局部变量";
console.log(text2); //局部变量只能在函数中使用
}
</script>
3.全局变量和局部变量一些常见问题
3.1全局变量跟局部变量重名
当全局变量跟局部变量重名时,局部变量的scope会覆盖掉全局变量的scope,当离开局部变量的scope后,又重回到全局变量的scope。
<script>
var str = "我是全局变量";
function b() {
var str = "我是局部变量";
console.log(str); //结果:我是局部变量
}
b();
console.log(str);//结果:我是全局变量
</script>
当全局变量遇上局部变量时,怎样使用全局变量呢?用window.globalVariableName。
<script>
var a = 1; //全局变量
! function b() {
var a = 2; //局部变量a在这行定义
console.log(window.a); //a为1,这里的a是全局变量哦!
console.log(a); //a为2,这里的a是局部变量哦!
}()
console.log(a); //a为1,这里并不在function b scope内,a的值为全局变量的值
</script>
3.2 零散变量的问题
Javascript在执行前会对整个脚本文件的声明部分做完整分析(包括局部变量),从而确定变量的作用域。所以Javascript允许在函数的任意地方声明变量,无论在哪里声明,效果都等同于在函数顶部进行声明。怎么理解呢?看下面一个例子:
<script>
var str = "我是全局变量";
! function b() {
console.log(str); //结果:undefined
var str = "我是局部变量";
console.log(str); //结果:我是局部变量
}()
</script>
为什么不是: 我是全局变量 和 我是局部变量? 原因很简单:对JavaScript而言,只要变量是在同一个范围(函数)里,就视为已经声明,哪怕是在变量声明前就使用。上面的代码相当于:
<script>
var str = "我是全局变量";
! function b() {
var str; //系统自动赋值为 str = undefined
console.log(str); //结果:undefined
var str = "我是局部变量";
console.log(str); //结果:我是局部变量
}()
</script>
3.3. 变量释放问题
请看下面的代码:
<script>
var a = "hello"; //全局变量
window.b = "word"; //全局变量
delete a;
delete b;
console.log(typeof a); //结果:string
console.log(typeof b); //结果:undefined
! function b() {
var c = 1; //局部变量
d = 2; //全局变量
delete c;
delete d;
console.log(typeof c); //结果:number
console.log(typeof d); //结果:undefined
}()
</script>
结论:
- 使用 var 创建的变量不能使用 delete 释放内存。
- 不使用 var 创建的变量可以使用 delete 释放内存。
总结:
1.在过程体内(包括方法function(){},对象Object o={})内的对象)加var保留字则为局部变量,其他情况下都是全局变量(无论是否使用var。不进行声明而直接使用全局变量会报错(可以隐式声明),而局部变量先使用后声明则不会报错,只是值为undefined。 2.全局变量跟局部变量重名时,局部变量的范围会覆盖掉全局变量的范围,当离开局部变量的范围后,又重回到全局变量的范围。(若想指定是全局变量可以使用 window.globalVariableName。 3.Javascript允许在函数的任意地方声明变量,无论在哪里声明,效果都等同于在函数顶部进行声明。 4.使用 var 创建的变量不能使用 delete 释放内存,其他方式创建的变量可以使用 delete 释放内存。
一般来说全局变量所带来的 bug 问题非常多,所以最好尽量少用全局变量。另外,声明变量最好带 var, 不应使用带 var 的链式赋值,在函数体内定义变量时,最好把变量声明放在顶部,防止出现变量没有被定义就被使用的逻辑错误。
- 深入线程
- 【插件开发】—— 2 插件入门
- 线程间通讯:WaitHandler使用实例及分析
- 域名Deskbike.com刚注册没多久就以五位数结拍
- 一起Polyfill系列:Function.prototype.bind的四个阶段
- winform实现拼图游戏
- 一起Polyfill系列:让Date识别ISO 8601日期时间格式
- Oracle 监听器无法启动(TNS-12537,TNS-12560,TNS-00507)
- Javascript Prototypes之旅(A Plain English Guide to JavaScript Prototypes译文)
- Python补充03 Python内置函数清单
- 不懂JQuery的孩子:自封装Ajax函数
- .Net魔法堂:史上最全的ActiveX开发教程——ActiveX与JS间交互篇
- 飓风“桑迪”路径图的制作
- 根据标准word模板生成word文档类库(开源)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 「网络IO套路」当时就靠它追到女友
- 起个简单枯燥的标题:找出连续差相同的数字
- 10分钟带你搞懂代理模式、静态代理、JDK+CGLIB动态代理
- 握草!某程序员竟然在深夜偷偷在代码里下毒!
- 自然资源部贡献的Landuse数据(2000、2010、2020)
- LoRa节点开发——SDK整体设计思路
- 01 . Nginx简介及部署
- 02 . Nginx平滑升级和虚拟主机
- LoRa节点开发——LoRaWAN节点入网代码详解
- 03 . Nginx日志配置及日志切割
- 04 . Nginx的Rewrite重写
- 05 . Nginx的反向代理与负载均衡
- 06 . Nginx静态资源缓存
- 07 . Nginx常用模块及案例
- 08 . Nginx状态码