扫码关注官方订阅号
对于上面这段代码,为什么单单var str1 = "c"就会使得str1的值为undefined呢?主要的疑惑和请教:
alert(str1)语句位于var str1 = "c"之前,为什么会受它的影响呢?
此过程中全局变量str1发生了什么变化?
学习是最好的投资!
参考这里的变量声明提升部分
这是JavaScript的变量声明提升效果 - hoisting以上代码在运行时会变为这样
<script type="text/javascript"> var str1="b"; function test(){ var str1; alert(str1); str1 = "c"; } test(); </script>
js只有函数作用域,所以alter(str1)时现在本函数作用域查找变量,此时只是进行了var str1 那么返回的就是undefined,如果本函数作用域没有此变量的声明,才会依据作用域链向外寻找。
var str1
undefined
前面的回答都不错补充局部变量与全局变量的关系。设置一个全局变量,需在任何函数之外用var声明,对所有函数有效。设置一个局部变量,就在需要的地方var声明。
var a=1; function f(){ var a=2; alert(a); } alert(a);
上面的代码中,全局变量a的值为1。局部变量a为2。在一个function中,如果全局变量与局部变量重名,局部变量优先级高。所以在f()的alert中,a的值为2。然而局部变量顾名思义,就是只在局部范围内生效的函数。所以a=2只在f()中生效,所以第二个alert的值为1。再结合上面的回答,就解决了。另外,更改一个函数的值的方法是直接赋值,不加var
题主的第一个疑问,是关于变量提升的问题。
原代码
var str1="b"; function test(){ alert(str1); var str1 = "c"; } test();
等同于
function test(){ var str1; alert(str1); str1 = "c"; } var str1; str1="b"; test();
简单点说,JavaScript中只有用var声明的变量(ES6里新出的声明变量的let和声明常量的const都没这个讲究)和函数声明(注意!是函数声明!不包括var f = function(){}等等这样的函数表达式!)才有变量提升现象。
var
let
const
var f = function(){}
其中,函数声明优先级高于用 var 声明的变量,JavaScript引擎会先解析。
对函数声明来说,变量提升会带着函数体一起放到区域执行环境的前端;对变量声明来说,只提升变量,不提升声明。(比如你代码中的str1声明被提前,赋值还保留在原来的那一行。)
题主的第二个问题,是关于执行环境和作用域链的问题。
此过程中全局变量str1没变化,因为不关它事。
作用域链其实是个保证访问顺序的东西。这顺序是由里往外,由下至上的。作用域链的前端始终是当前执行代码所在环境的变量对象。在当前环境中拿到了它想要的值(别管是什么值,哪怕是个只声明未赋值的undefined),就不会沿着作用域链继续向上查找了。
请注意js的变量声明有hoisting 变量提升...函数内执行的相当于
var str1;alert(str1);str1 = 'a';
由于变量提升的原因,实际执行的代码相当于是
函数内部有定义变量名为str1的变量,这个时候他回覆盖函数外的同名变量,而且根据变量提升原理,在执行执行alert(str1)之前,str1只是在函数内部进行了定义,但并没有实际的赋值。所以输出也就是undifined了
微信扫码关注PHP中文网服务号
QQ扫码加入技术交流群
Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部
参考这里的变量声明提升部分
这是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了