ex:
// 全局变量
var foo = 1;
var bar = 2;
var i = 2;
function test(i) {
// 函数 test 内的局部作用域
i = 5;
var foo = 3;
bar = 4;
}
test(10);
foo 和 i 是函数 test 内的局部变量,而对 bar 的赋值将会覆盖全局作用域内的同名变量。
为什么i属于局部变量 但是i 没有显示var 声明不应该是全局变量?
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
题主,我终于帮你找到了根本原因。下面这段话引自ECMAScript 5.1的10.5节:
这段话说明了:不论是在函数中用
var声明的变量,还是函数的参数,都是绑定到执行上下文中的变量环境中的环境记录项的。换句话说,JS引擎对它们的处理方式是没有区别的,都是作为局部变量。要说区别的话,只是它们的初始化方式不一样。还是那句话:有问题就找规范。
最后,纠正一下几个回答中的错误:题主说的没错,那个
i = 5中的i就是局部变量,这个i跟函数的参数i是同一个东西。说i是全局变量的同学们,都去面壁吧 :)我觉得你的逻辑有点诡异
而且我觉得你需要理解一下javascript的参数:
每个函数
function都的原型都是function.prototype函数原型。而函数原型有一个属性为
arguments,是个数组。每次
function(a,b,c,...)将abc参数赋值给function执行时。就相当于把a,b,c,...这些参数赋值给
arguments数组。你可以试一试,你看看下面的函数
这样扭回头来看:
arguments数组函数原型的属性是每一个函数里的变量
自然你在函数内部对它进行赋值
log出来肯定是赋值后的值
如果还有什么不明白的,推荐《javascript高级程序设计》
题设不知所云。
什么迹象表明它是你所认为的局部变量,你倒是说呀!
你说的很对
这个没有为什么,就是这么规定的。
具体的可以参考我的博客:
http://zonxin.github.io/post/2015/10/javascript-hoisting/
上面的代码在声明解析阶段,再全局环境的作用域下注册声明变量foo/bar/i及函数对象test
在函数test作用域下注册声明foo/i,并引用bar这个全局作用域下的变量bar,此时i为函数的参数变量而非全局变量i,只是just名字相同而已~~~,foo通过var关键字声明为函数内部变量
是不是和闭包的行为很类似啊,对了JS全局环境就是一个大的闭包~~~~
在JS代码在声明解析阶段是不执行代码的
在test函数执行阶段,传入参数10,将其赋值给参数变量i,此时i=10;
i再被重新赋值为5,foo被赋值为3,bar被赋值为4
全局变量bar就被赋值为4,为变量foo和i随着函数的执行完毕,被从执行栈中清除掉了,外部不可再被访问到~~~
和下面的代码一样一样的~~~
这里实际上涉及到了"JS词法分析"的知识,楼主可以搜索“JS词法分析"了解更多。
补充:
楼主修改了问题:为什么i属于局部变量 但是i 没有显示var 声明不应该是全局变量?
表示看问题没看懂问啥呢,看答案才看懂,感情是在纠结函数参数和全局变量问题,别看它们都叫i,你得就近啊……
规范规定函数的形参为局部变量。
一个靠谱的答案都没没有,最后只能强记了!