变量的作用域和变量提升
来源:互联网 发布:淘宝卖家快点到货款 编辑:程序博客网 时间:2024/04/27 19:18
京东面试题,面试官小姐姐给出了一道题:
var a = 100;function test(){ console.log(a); a = 10; console.log(a); console.log(this.a); var a;}test();
问我这三个会打印出来的值是什么?
好吧我这个还以为是要考我闭包的问题,后来一想是个变量提升的问题(好吧好吧,是小姐姐看我太尴尬了,就给我讲了一下)
回来研究一下这个变量的作用域和变量提升:
一、作用域:
一个变量的作用域(scope)是程序源代码中定义这个变量的区域。
全局变量拥有全局作用域,在javaScript代码中任何地方都有定义的。
然而在函数内声明的变量只是在函数内部有定义,他们是局部变量,作用域也只是在局部。
在函数体内,局部变量的优先级要高于全局变量。如果在函数体内重新声明一个与局部变量重名的变量,局部变量就会覆盖全局变量的值。
来看个例子:
var num="100";function scope(){ var num="10"; function innerScope(){ var num = "1"; console.log(scope);//输出:1 } innerScope(); console.log(num);//输出:10}scope();console.log(num);//输出:100
这个例子会打印三个数,分别是1,10,100;
局部变量的作用域仅仅在函数内部,出了函数体之后,局部变量就会被销毁。
在innerScope()函数中,虽然又声明了一个num,但是innerScope()中的num是局部变量,只是与全局变量的名字相同,并不是全局变量,所以,虽然在该函数中把num赋值为1,但这仅仅是一个与全局变量名称相同的一个变量而已,并没有改变全局变量的值。
再来看一个例子:
var num="100";function scope(){ var num="10"; function innerScope(){ num = "1"; console.log(scope);//输出:1 } innerScope(); console.log(num);//输出:1}scope();console.log(num);//输出:100
上面这部分代码中,在innerScope()函数中,我们并没有用var来声明num,所以,在这里的num的作用域就被提升了,即我们将scope中的num的值重置了,所以在输出的时候输出的结果为嵌套作用域内的局部变量。
二、变量提升
在Javascript中,函数及变量的声明都将被提升到函数的最顶部。
在js中,变量的声明会被解析器悄悄的提升到方法体的最顶部,但是需要注意的是,提升的仅仅是变量的声明,变量的赋值并不会被提升,我们需要注意的是,函数的声明与变量的声明是不一样的。函数的函数体也会被一起提升。
函数表达式和变量表达式只是其声明被提升,函数声明是函数的声明和实现都被提升。
所以上面那个题就很好理解了。
我们再来看一下这个题:
var num="100";function scope(){ var num="10"; function innerScope(){ var num = "1"; console.log(scope);//输出:1 } innerScope(); console.log(num);//输出:10}scope();console.log(num);//输出:100
- 因为变量提升,a提升到最前面,声明未赋值,所以第一个就会打印undefined;
- 第二个在a声明之后,而且a赋值为10,所以第二个打印出来10;
- 第三个,因为test()是在window下调用的;this指的是test()调用的作用域,所以第三个打印100;
看一个函数提升的例子:
<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 alert(v); //undefined foo(); //local foo bar(); //报错,缺少对象 bar = function() { alert("local bar"); }; v = "local"; } */ </script>
- 变量的作用域和变量提升
- javaScript的作用域和变量提升
- javascript的变量提升和作用域
- JavaScript的作用域和变量提升
- JavaScript变量作用域和变量提升
- 作用域 变量的提升
- Javascript作用域和变量提升
- Javascript 作用域和变量提升
- Javascript 作用域和变量提升
- Javascript作用域和变量提升
- Javascript作用域和变量提升
- Javascript作用域和变量提升
- Javascript作用域和变量提升
- Javascript作用域和变量提升
- Javascript作用域和变量提升
- JavaScript作用域和变量提升
- Javascript作用域和变量提升
- Javascript作用域和变量提升
- Python——数据运算
- PHP 两种方法取时间段
- SSM框架解读 Mapper.xml 增删改查操作
- jdk与jre的区别
- 数据不平衡时分类器性能评价(ROC曲线)
- 变量的作用域和变量提升
- 在二维数组中*a,a,a[0] ,a[0][0] ,a[1] ,&a[1] 的区别
- LR录制时会出现总是无法打开IE浏览器http://www.cnblogs.com/workmore/p/6100933.html
- GCC 编译依赖库和程序运行依赖库设置
- The Closest Pair Problem UVA
- oracle
- jqgrid将列字典值转换成中文词义[实例]
- 数据权限
- plsql导出Oracle数据库的步骤示意图