js中全局变量和局部变量以及变量声明提升
- <script type="text/javascript">
- var a = "Hello";
- function test(){
- var a;
- alert(a);
- a = "World";
- alert(a);
- }
- </script>
- <script type="text/javascript">
- var a = "Hello";
- function test(){
- alert(a);
- a = "World";
- alert(a);
- }
- </script>
我想,好简单呀,不就是全局变量跟局部变量的scope问题吗?我说:"当全局变量跟局部变量重名时,局部变量的scope会覆盖掉全局变量的scope,当离开局部变量的scope后,又重回到全局变量的scope。所以两段代码运行的结果分别为:1) undefined World 2) Hello World。然后我随意编了如下一个例子给她:
- <script>
- var a =1;
- function test(){
- alert(a);
- var a = 2;
- alert(a);
- }
- test();
- alert(a);
- </script>
大家猜结果等于多少?是输出1 2 1 吗?嗯嗯,当我把测试case发给她之前也是这么认为的,但测试输出后……运行结果是 undefined 2 1。当时百思不得其解,问了谷老师才知道,我对JS还不是非常了解,所以痛下苦功,学习+测试,总结如下:
一、Javascript的变量的scope是根据方法块来划分的(也就是说以function的一对大括号{ }来划分)。切记,是function块,而for、while、if块并不是作用域的划分标准,可以看看以下几个例子:
- <script>
- function test2(){
- alert ("before for scope:"+i); // i未赋值(并不是未声明!使用未声明的变量或函数全抛出致命错误而中断脚本执行)
- // 此时i的值是underfined
- for(var i=0;i<3;i++){
- alert("in for scope:"+i); // i的值是 0、1、2, 当i为3时跳出循环
- }
- alert("after for scope:"+i); // i的值是3,注意,此时已经在for scope以外,但i的值仍然保留为3
- while(true){
- var j = 1;
- break;
- }
- alert(j); // j的值是1,注意,此时已经在while scope以外,但j的值仍然保留为1
- if(true){
- var k = 1;
- }
- alert(k); //k的值是1,注意,此时已经在if scope以外,但k的值仍然保留为1
- }
- test2();
- //若在此时(function scope之外)再输出只存在于test2 这个function scope里的 i、j、k变量会发生神马效果呢?
- alert(i); //error! 没错,是error,原因是变量i未声明(并不是未赋值,区分test2函数的第一行输出),导致脚本错误,程序到此结束!
- alert("这行打印还会输出吗?"); //未执行
- alert(j); //未执行
- alert(k); //未执行
- </script>
二、Javascript在执行前会对整个脚本文件的声明部分做完整分析(包括局部变量),从而确定实变量的作用域。怎么理解呢?看下面一个例子:
- <script>
- var a =1;
- function test(){
- alert(a); //a为undefined! 这个a并不是全局变量,这是因为在function scope里已经声明了(函数体倒数第4行)一个重名的局部变量,
- //所以全局变量a被覆盖了,这说明了Javascript在执行前会对整个脚本文件的定义部分做完整分析,所以在函数test()执行前,
- //函数体中的变量a就被指向内部的局部变量.而不是指向外部的全局变量. 但这时a只有声明,还没赋值,所以输出undefined。
- a=4
- alert(a); //a为4,没悬念了吧? 这里的a还是局部变量哦!
- var a; //局部变量a在这行声明
- alert(a); //a还是为4,这是因为之前已把4赋给a了
- }
- test();
- alert(a); //a为1,这里并不在function scope内,a的值为全局变量的值
- </script>
三,当全局变量跟局部变量重名时,局部变量的scope会覆盖掉全局变量的scope,当离开局部变量的scope后,又重回到全局变量的scope,而当全局变量遇上局部变量时,怎样使用全局变量呢?用window.globalVariableName。
- <script>
- var a =1;
- function test(){
- alert(window.a); //a为1,这里的a是全局变量哦!
- var a=2; //局部变量a在这行定义
- alert(a); //a为2,这里的a是局部变量哦!
- }
- test();
- alert(a); //a为1,这里并不在function scope内,a的值为全局变量的值
- </script>
总结下
1、js有两级作用域,全局和局部,局部也叫函数作用域
2、全局作用域的变量局部可以使用,局部作用域的变量只能在函数体内使用
3、var和function声明的变量都声明提前,赋值留在原地
4、如果局部和全局变量重名,优先使用局部变量
5、第3条和第4条,解释了全局和局部都有相同变量名的时候,而在函数体内打印的变量是undefined
js中全局变量和局部变量以及变量声明提升的更多相关文章
- JS的全局变量与局部变量及变量的提升
遇到全局变量与局部变量的时候总是出一些或多或少的问题,于是专门花时间去认真研究了一下全局变量与局部变量. 这是在网上看到的一个关于全局变量与局部变量的代码,看了下作者的解析,自己也进行了研究. < ...
- PHP和JS中全局变量和局部变量
一,PHP中全局变量和局部变量 php与C++中对全局变量和局部变量定义类似,全局变量:函数外定义的变量,在全局通用:局部变量:在函数内定义的变量,只在函数内有效.PHP中变量范围跨越了include ...
- 今天才知道原来我还没弄清楚js中全局变量和局部变量的定义...
查资料看到这段还不错,来源:原文:https://blog.csdn.net/czh500/article/details/80429133 粘过来记录一下... 1.使用var声明变量,在方法内部是 ...
- 一个经典的js中关于块级作用域和声明提升的问题
function functions(flag) { if (flag) { function getValue() { return 'a'; } } else { function getValu ...
- 解读JavaScript中的Hoisting机制(js变量声明提升机制)
hoisting机制:javascript的变量声明具有hoisting机制,JavaScript引擎在执行的时候,会把所有变量的声明都提升到当前作用域的最前面. 知识点一:javascript是没有 ...
- python中全局变量和局部变量的一个小坑
python 中全局变量和局部变量在使用过程中的一个容易出错的地方 什么是全局变量 python中,在函数外部声明的变量可以叫做全局变量. x = 10 def fn1(): pass fn1() 什 ...
- js变量声明提升
1.变量提升 根据javascript的运行机制和javascript没有块级作用域这个特点,可以得出,变量会声明提升移至作用域 scope (全局域或者当前函数作用域) 顶部的. 变量声明提升至全局 ...
- [Effective JavaScript 笔记] 第12条:理解变量声明提升
js支持词法作用域,即除了极少的例外,对变量的引用会被绑定到声明变量最近的作用域中. js不支持块级作用域,即变量定义的作用域并不是离其最近的封闭语句或代码块,而是包含它们的函数. 不了解这个会产生一 ...
- JS高级. 05 词法作用域、变量名提升、作用域链、闭包
作用域 域,表示的是一个范围,作用域,就是作用范围. 作用域说明的是一个变量可以在什么地方被使用,什么地方不能被使用. 块级作用域 JavaScript中没有块级作用域 { var num = 123 ...
随机推荐
- 在linux(deepin)系统下查看当前ip地址与用户名
在linux(deepin)系统下查看当前ip地址与用户名 查看当前ip地址 方式一: hostname -I 方式二: ifconfig -a 如下图所示: 其中192.168.11.66即为当前系 ...
- 4 - 基于ELK的ElasticSearch 7.8.x技术整理 - 高级篇( 续 ) - 更新完毕
0.前言 这里面一些理论和前面的知识点挂钩的,所以:建议看一下另外3篇知识内容 基础篇:https://www.cnblogs.com/xiegongzi/p/15684307.html java操作 ...
- Linux 安装并启用 PHP-FPM
首先,在编译时带上 --enable-fpm 参数: [root@localhost local]# yum -y install libxml2 libxml2-devel gd gd-devel ...
- django 使用createView创建视图是form_valid()没有通过?
django 使用createView创建视图是form_valid()没有通过的原因: fields中定义的字段要与from表单中的字段相对应 修改后 接着又报错: 查看没有取到id,最后通过req ...
- spring boot 集群 + Nginx --- 心得
1.前言 已经掌握了spring cloud 得使用 ,但这是在内部网络做业务 ,现在需要 在外部网络 访问内部网络 服务 ,引入了 服务端负载均衡 Nginx , Nginx 根据预定的策略 ,将请 ...
- vue爬坑之路(插件安装)
npm install vue-table-with-tree-grid --save import ZkTable from 'vue-table-with-tree-grid' Vue.use(Z ...
- Elasticsearch基础知识学习
概要 ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticsearch是用Java开发的,并作为Ap ...
- 一键AI着色,黑白老照片画面瞬间鲜活
很多老照片或者电影受时代技术所限制,只能以黑白形式保存:经过编辑后的黑白视频和图片早已丢失彩色原图,这对于保存者来说都十分遗憾.如何能将单一乏味.陈旧斑驳的黑白照片变成鲜活亮丽的彩色照片,从照片中重新 ...
- 生产环境上,哨兵模式集群Redis版本升级应用实战
背景: 由于生产环境上所使用的Redis版本并不一致,好久也没有更新,为了避免版本不同对Redis集群造成影响,从而升级为统一Redis版本! 1.集群架构 一主两从三哨兵: 2.升级方案 (1)升级 ...
- C# 给PDF文档设置过期时间
我们可以给一些重要文档或者临时文件设置过期时间和过期信息提示来提醒读者或管理者文档的时效性,并及时对文档进行调整.更新等.下面,分享通过C#程序代码来给PDF文档设置过期时间的方法. 引入dll程序集 ...