关于js中变量作用于和变量提升的那些事
来源:互联网 发布:pc端登录淘宝卖家中心 编辑:程序博客网 时间:2024/06/06 01:48
一个变量的作用域(scope)是程序源代码中定义这个变量的区域。
全局变量拥有全局作用域,在javaScript代码中任何地方都有定义的。
然而在函数内声明的变量只是在函数内部有定义,他们是局部变量,作用域也只是在局部。
在函数体内,局部变量的优先级要高于全局变量。如果在函数体内重新声明一个与局部变量重名的变量,局部变量就会覆盖全局变量的值。
var scope="全局变量"; function checkscope(){ var scope="局部变量"; function nested(){ var scope = "嵌套作用域内的局部变量"; alert(scope);//输出:嵌套作用域内的局部变量 } nested(); alert(scope);//输出:局部变量 } checkscope(); alert(scope);//输出:全局变量
从上面的例子中可以看出,局部变量的作用域仅仅在函数内部,出了函数体之后,局部变量就会被销毁。
在nested()函数中,虽然又声明了一个scope,但是nested()中的scope是局部变量,只是与全局变量的名字相同,并不是全局变量,所以,虽然在该函数中把scope赋值为”嵌套作用域内的局部变量”,但这仅仅是一个与全局变量名称相同的一个变量而已,并没有改变全局变量的值。
我们可以通过以下这个例子来进一步理解函数作用域的问题。
var scope="全局变量"; function checkscope(){ var scope="局部变量"; function nested(){ scope = "嵌套作用域内的局部变量"; alert(scope);//输出:嵌套作用域内的局部变量 } nested(); alert(scope);//输出:嵌套作用域内的局部变量 } checkscope(); alert(scope);//输出:全局变量
看到这里是不是有一些懵逼了,这和刚才不是一样的吗,为什么第二次弹框不一样了呢?
上面这部分代码中,在nested()函数中,我们并没有用var来声明scope,所以,在这里的scope的作用域就被提升了,即我们将checkscope中的scope的值重置了,所以在输出的时候输出的结果为嵌套作用域内的局部变量。
之前学习过c或java等其他编程语言的童鞋会知道,在c语言中会有块级作用域这个概念。
C语言中块级作用域是以成对的花括号来界定的,也就是说除了函数代码块外,if、for等结构也属于块级作用域。
下面这个例子可以帮助我们理解一下:
#include <stdio.h> int main() { int x = 1; printf("%d, ", x); // 1 if (1) { int x = 2; printf("%d, ", x); // 2 } printf("%d\n", x); // 1 }
在c或c++、java中,变量的作用域是由成对的花括号来界定的,比如if中的x,在if中,x的值为2。但是,当程序运行出了if花括号以后,if中的变量x的作用域就结束了,并不会对if以外的x造成影响。但是这在js中是不一样的~
弄明白了变量的作用域之后再来考虑变量提升就简单多了。
在Javascript中,函数及变量的声明都将被提升到函数的最顶部。
在js中,变量的声明会被解析器悄悄的提升到方法体的最顶部,但是需要注意的是,提升的仅仅是变量的声明,变量的赋值并不会被提升。
function foo() { if (false) { var x = 1; } return; var y = 1; } function foo() { var x, y; if (false) { x = 1; } return; y = 1; }
其实上面两段代码是一模一样的。
变量的声明会被提升,赋值不会被提前。我们需要注意的是,函数的声明与变量的声明是不一样的。函数的函数体也会被一起提升。但是,函数的声明我们可以用两种方法。
function test() { var test1 = function () { // 变量指向函数表达式 alert("this is test1!"); } function test2() { // 函数声明 函数名为test2 alert("this is test2!"); } } test();
在上面这个例子中,对于test1来说,是声明了一个变量,这个变量指向这个函数表达式,所以解析是会将var test1 提升,而后面对变量的赋值不会被提升。对于test2,解析是会把整个函数体一起提升。所以如果我们在函数体的开始运行两个函数,test1报错TypeError “test1 is not a function” ,test2则会弹出this is test2!。
我们可以用这个例子加深一下理解。
<script language="javascript" type="text/javascript"> //在全局对象中声明两个全局函数,反模式 function foo() { alert("global foo"); } function bar() { alert("global bar"); } //定义全局变量 var v = "global var"; function hoistMe() { alert(typeof foo); //function alert(typeof bar); //undefined alert(v); //undefined //为什么bar函数和变量v是未定义而不是全局变量中定义的相应的函数变量呢? //因为函数里面定义了同名的函数和变量,无论在函数的任何位置定义这些函数和 //和变量,它们都将被提升到函数的最顶部。 foo(); //local foo bar(); //报错,TypeError "bar is not a function" //函数声明,变量foo以及其实现被提升到hoistMe函数顶部 function foo() { alert("local foo"); } //函数表达式,仅变量bar被提升到函数顶部,实现没有被提升 var bar = function() { alert("local bar"); }; //定义局部变量 var v = "local"; } (function() { hoistMe(); })(); //函数表达式和变量表达式只是其声明被提升,函数声明是函数的声明和实现都被提升。 /**由于函数提升的效果,hoistMe方法相当于 function hoistMe() { //函数声明,变量foo以及其实现被提升到hoistMe函数顶部 function foo() { alert("local foo"); } //函数表达式,仅变量bar被提升到函数顶部,实现没有被提升(同变量提升) var bar = undefined; //变量声明被提升 var v = undefined; alert(typeof foo); //function alert(typeof bar); //undefined foo(); //local foo bar(); //报错,缺少对象 bar = function() { alert("local bar"); }; v = "local"; } */ </script>
- 关于js中变量作用于和变量提升的那些事
- JS 函数作用域及变量提升那些事!
- 变量的作用域和变量提升
- 关于js 的变量提升
- 关于js的变量提升
- 关于js中变量的作用范围
- js的变量提升和函数提升
- js的变量提升和函数提升
- js中变量提升
- js中变量提升
- js变量作用域--变量提升
- javaScript的作用域和变量提升
- javascript的变量提升和作用域
- JavaScript的作用域和变量提升
- 关于JS里面的变量提升
- JS中变量和函数的提升机制(hoisting)
- JavaScript变量作用域和变量提升
- 作用域 变量的提升
- 杭电4521小明系列问题——小明序列
- Android使用ScrollView嵌套ListView实现复杂数据列表选择处理
- HDU1087:Super Jumping! Jumping! Jumping!
- FreeSwitch 信道状态(Channel Status)
- HDOJ -- 2066 一个人的旅行
- 关于js中变量作用于和变量提升的那些事
- TOJ 3259.Mysterious Number(埃式筛法)
- Android Studio 掌握这些调试技巧,Debug能力不能再高啦
- 安卓如何利用资源名称获得资源Id
- 借鉴系统UITableView的设计思想,自定义一个"花瓣"菜单
- php 将中文字符串截取为数组
- Two Bases
- Trie树编程实现
- ATOM -- A hackable text editor for the 21st Century