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 声明不应该是全局变量?
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 声明不应该是全局变量?
我觉得你的逻辑有点诡异
var i=9;
function foo(i){
i =5; // i 为函数声明时的参数啊,为什么还需要再用var声明一次
console.log(i); //因为i经过赋值,所以输出5
}
而且我觉得你需要理解一下javascript的参数:
每个函数function
都的原型都是function.prototype
函数原型。
而函数原型有一个属性为arguments
,是个数组。
每次function(a,b,c,...)
将abc参数赋值给function
执行时。
就相当于把a,b,c,...这些参数赋值给arguments
数组。
你可以试一试,你看看下面的函数
var i=9;
function foo(i){
arguments[0] =5;
console.log(i);
}
foo(i) //输出5,和你题目中的函数输出的一样;
这样扭回头来看:arguments
数组函数原型的属性
是每一个函数里的变量
自然你在函数内部对它进行赋值
log出来肯定是赋值后的值
如果还有什么不明白的,推荐《javascript高级程序设计》
你说的很对
这个没有为什么,就是这么规定的。
具体的可以参考我的博客:
http://zonxin.github.io/post/2015/10/javascript-hoisting/
var foo = 1;//声明全局变量foo
var bar = 2;//声明全局变量bar
var i = 2;//声明全局变量i
//声明函数一个带1个形参的函数test
function test(i) {
i = 5;
var foo = 3;//申明函数内部变量foo
bar = 4;
}
test(10);
console.log(foo);//1
console.log(bar);//4
console.log(i);//2
上面的代码在声明解析阶段,再全局环境的作用域下注册声明变量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随着函数的执行完毕,被从执行栈中清除掉了,外部不可再被访问到~~~
和下面的代码一样一样的~~~
var foo = 1;
var bar = 2;
var i = 2;
//声明函数一个带1个形参的函数test
function test(k) {
k = 5;
var foo = 3;
bar = 4;
}
test(10);
console.log(foo);//1
console.log(bar);//4
console.log(i);//2
console.log(k);//ReferenceError: k is not defined
var i=9;//定义了一个全局变量i
function foo(i){ //这里的i是参数
i =5; // 这里的i首先肯定不是局部变量,如果要定义局部变量的话,需要加个var 如果不加的话,定义的是全局变量。
//但这里的情况不是这样的,因为i是参数,所以,这里实际上你是把参数重新赋值了。这在实际中是肯定不会这样写的。
console.log(i);
}
foo(7);//结果是5
这里实际上涉及到了"JS词法分析"的知识,楼主可以搜索“JS词法分析"了解更多。
补充:
楼主修改了问题:为什么i属于局部变量 但是i 没有显示var 声明不应该是全局变量?
i其实是函数的参数,函数的参数作用域当然只能在函数内部。
10 回答11.3k 阅读
5 回答4.9k 阅读✓ 已解决
4 回答3.2k 阅读✓ 已解决
2 回答2.8k 阅读✓ 已解决
3 回答2.4k 阅读✓ 已解决
3 回答2.2k 阅读✓ 已解决
2 回答2.6k 阅读✓ 已解决
题主,我终于帮你找到了根本原因。下面这段话引自ECMAScript 5.1的10.5节:
这段话说明了:不论是在函数中用
var
声明的变量,还是函数的参数,都是绑定到执行上下文中的变量环境中的环境记录项的。换句话说,JS引擎对它们的处理方式是没有区别的,都是作为局部变量。要说区别的话,只是它们的初始化方式不一样。还是那句话:有问题就找规范。
最后,纠正一下几个回答中的错误:题主说的没错,那个
i = 5
中的i就是局部变量,这个i跟函数的参数i是同一个东西。说i是全局变量的同学们,都去面壁吧 :)