javascript中关于函数中赋值的疑问
<script type="text/javascript">
var str1="b";
function test(){
alert(str1);
var str1 = "c";
}
test();
</script>
对于上面这段代码,为什么单单var str1 = "c"就会使得str1的值为undefined呢?
主要的疑惑和请教:
alert(str1)语句位于var str1 = "c"之前,为什么会受它的影响呢?
此过程中全局变量str1发生了什么变化?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
参考这里的变量声明提升部分
这是JavaScript的变量声明提升效果 - hoisting
以上代码在运行时会变为这样
js只有函数作用域,所以alter(str1)时现在本函数作用域查找变量,此时只是进行了
var str1
那么返回的就是undefined
,如果本函数作用域没有此变量的声明,才会依据作用域链向外寻找。前面的回答都不错
补充局部变量与全局变量的关系。
设置一个全局变量,需在任何函数之外用var声明,对所有函数有效。
设置一个局部变量,就在需要的地方var声明。
上面的代码中,全局变量a的值为1。局部变量a为2。
在一个function中,如果全局变量与局部变量重名,局部变量优先级高。所以在f()的alert中,a的值为2。
然而局部变量顾名思义,就是只在局部范围内生效的函数。所以a=2只在f()中生效,所以第二个alert的值为1。
再结合上面的回答,就解决了。
另外,更改一个函数的值的方法是直接赋值,不加var
题主的第一个疑问,是关于变量提升的问题。
原代码
等同于
简单点说,JavaScript中只有用
var
声明的变量(ES6里新出的声明变量的let
和声明常量的const
都没这个讲究)和函数声明(注意!是函数声明!不包括var f = function(){}
等等这样的函数表达式!)才有变量提升现象。其中,函数声明优先级高于用 var 声明的变量,JavaScript引擎会先解析。
对函数声明来说,变量提升会带着函数体一起放到区域执行环境的前端;对变量声明来说,只提升变量,不提升声明。(比如你代码中的str1声明被提前,赋值还保留在原来的那一行。)
题主的第二个问题,是关于执行环境和作用域链的问题。
此过程中全局变量str1没变化,因为不关它事。
作用域链其实是个保证访问顺序的东西。这顺序是由里往外,由下至上的。作用域链的前端始终是当前执行代码所在环境的变量对象。在当前环境中拿到了它想要的值(别管是什么值,哪怕是个只声明未赋值的undefined),就不会沿着作用域链继续向上查找了。
请注意js的变量声明有hoisting 变量提升...函数内执行的相当于
var str1;
alert(str1);
str1 = 'a';
由于变量提升的原因,实际执行的代码相当于是
函数内部有定义变量名为str1的变量,这个时候他回覆盖函数外的同名变量,而且根据变量提升原理,在执行执行alert(str1)之前,str1只是在函数内部进行了定义,但并没有实际的赋值。所以输出也就是undifined了